Merge pull request #4842 from peaklabs-dev/docker-cleanup-executions-ui
feat: Docker cleanup execution UI and some UI improvements
This commit is contained in:
@@ -25,17 +25,25 @@ class CleanupDocker
|
||||
"docker images --filter before=$helperImageWithVersion --filter reference=$helperImage | grep $helperImage | awk '{print $3}' | xargs -r docker rmi -f",
|
||||
];
|
||||
|
||||
$serverSettings = $server->settings;
|
||||
if ($serverSettings->delete_unused_volumes) {
|
||||
if ($server->settings->delete_unused_volumes) {
|
||||
$commands[] = 'docker volume prune -af';
|
||||
}
|
||||
|
||||
if ($serverSettings->delete_unused_networks) {
|
||||
if ($server->settings->delete_unused_networks) {
|
||||
$commands[] = 'docker network prune -f';
|
||||
}
|
||||
|
||||
$cleanupLog = [];
|
||||
foreach ($commands as $command) {
|
||||
instant_remote_process([$command], $server, false);
|
||||
$commandOutput = instant_remote_process([$command], $server, false);
|
||||
if ($commandOutput !== null) {
|
||||
$cleanupLog[] = [
|
||||
'command' => $command,
|
||||
'output' => $commandOutput,
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
return $cleanupLog;
|
||||
}
|
||||
}
|
||||
|
||||
24
app/Events/DockerCleanupDone.php
Normal file
24
app/Events/DockerCleanupDone.php
Normal file
@@ -0,0 +1,24 @@
|
||||
<?php
|
||||
|
||||
namespace App\Events;
|
||||
|
||||
use App\Models\DockerCleanupExecution;
|
||||
use Illuminate\Broadcasting\InteractsWithSockets;
|
||||
use Illuminate\Broadcasting\PrivateChannel;
|
||||
use Illuminate\Contracts\Broadcasting\ShouldBroadcast;
|
||||
use Illuminate\Foundation\Events\Dispatchable;
|
||||
use Illuminate\Queue\SerializesModels;
|
||||
|
||||
class DockerCleanupDone implements ShouldBroadcast
|
||||
{
|
||||
use Dispatchable, InteractsWithSockets, SerializesModels;
|
||||
|
||||
public function __construct(public DockerCleanupExecution $execution) {}
|
||||
|
||||
public function broadcastOn(): array
|
||||
{
|
||||
return [
|
||||
new PrivateChannel('team.'.$this->execution->server->team->id),
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -18,7 +18,7 @@ use App\Models\SwarmDocker;
|
||||
use App\Notifications\Application\DeploymentFailed;
|
||||
use App\Notifications\Application\DeploymentSuccess;
|
||||
use App\Traits\ExecuteRemoteCommand;
|
||||
use Exception;
|
||||
use Carbon\Carbon;
|
||||
use Illuminate\Bus\Queueable;
|
||||
use Illuminate\Contracts\Queue\ShouldBeEncrypted;
|
||||
use Illuminate\Contracts\Queue\ShouldQueue;
|
||||
@@ -317,7 +317,7 @@ class ApplicationDeploymentJob implements ShouldBeEncrypted, ShouldQueue
|
||||
throw $e;
|
||||
} finally {
|
||||
$this->application_deployment_queue->update([
|
||||
'finished_at' => now(),
|
||||
'finished_at' => Carbon::now()->toImmutable(),
|
||||
]);
|
||||
|
||||
if ($this->use_build_server) {
|
||||
@@ -1501,7 +1501,7 @@ class ApplicationDeploymentJob implements ShouldBeEncrypted, ShouldQueue
|
||||
]
|
||||
);
|
||||
if ($this->saved_outputs->get('commit_message')) {
|
||||
$commit_message = str($this->saved_outputs->get('commit_message'))->limit(47);
|
||||
$commit_message = str($this->saved_outputs->get('commit_message'));
|
||||
$this->application_deployment_queue->commit_message = $commit_message->value();
|
||||
ApplicationDeploymentQueue::whereCommit($this->commit)->whereApplicationId($this->application->id)->update(
|
||||
['commit_message' => $commit_message->value()]
|
||||
|
||||
@@ -331,6 +331,11 @@ class DatabaseBackupJob implements ShouldBeEncrypted, ShouldQueue
|
||||
if ($this->team) {
|
||||
BackupCreated::dispatch($this->team->id);
|
||||
}
|
||||
if ($this->backup_log) {
|
||||
$this->backup_log->update([
|
||||
'finished_at' => Carbon::now()->toImmutable(),
|
||||
]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -3,9 +3,12 @@
|
||||
namespace App\Jobs;
|
||||
|
||||
use App\Actions\Server\CleanupDocker;
|
||||
use App\Events\DockerCleanupDone;
|
||||
use App\Models\DockerCleanupExecution;
|
||||
use App\Models\Server;
|
||||
use App\Notifications\Server\DockerCleanupFailed;
|
||||
use App\Notifications\Server\DockerCleanupSuccess;
|
||||
use Carbon\Carbon;
|
||||
use Illuminate\Bus\Queueable;
|
||||
use Illuminate\Contracts\Queue\ShouldBeEncrypted;
|
||||
use Illuminate\Contracts\Queue\ShouldQueue;
|
||||
@@ -24,6 +27,8 @@ class DockerCleanupJob implements ShouldBeEncrypted, ShouldQueue
|
||||
|
||||
public ?string $usageBefore = null;
|
||||
|
||||
public ?DockerCleanupExecution $execution_log = null;
|
||||
|
||||
public function middleware(): array
|
||||
{
|
||||
return [(new WithoutOverlapping($this->server->uuid))->dontRelease()];
|
||||
@@ -38,37 +43,89 @@ class DockerCleanupJob implements ShouldBeEncrypted, ShouldQueue
|
||||
return;
|
||||
}
|
||||
|
||||
$this->execution_log = DockerCleanupExecution::create([
|
||||
'server_id' => $this->server->id,
|
||||
]);
|
||||
|
||||
$this->usageBefore = $this->server->getDiskUsage();
|
||||
|
||||
if ($this->manualCleanup || $this->server->settings->force_docker_cleanup) {
|
||||
CleanupDocker::run(server: $this->server);
|
||||
$cleanup_log = CleanupDocker::run(server: $this->server);
|
||||
$usageAfter = $this->server->getDiskUsage();
|
||||
$this->server->team?->notify(new DockerCleanupSuccess($this->server, ($this->manualCleanup ? 'Manual' : 'Forced').' Docker cleanup job executed successfully. Disk usage before: '.$this->usageBefore.'%, Disk usage after: '.$usageAfter.'%.'));
|
||||
$message = ($this->manualCleanup ? 'Manual' : 'Forced').' Docker cleanup job executed successfully. Disk usage before: '.$this->usageBefore.'%, Disk usage after: '.$usageAfter.'%.';
|
||||
|
||||
$this->execution_log->update([
|
||||
'status' => 'success',
|
||||
'message' => $message,
|
||||
'cleanup_log' => $cleanup_log,
|
||||
]);
|
||||
|
||||
$this->server->team?->notify(new DockerCleanupSuccess($this->server, $message));
|
||||
event(new DockerCleanupDone($this->execution_log));
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (str($this->usageBefore)->isEmpty() || $this->usageBefore === null || $this->usageBefore === 0) {
|
||||
CleanupDocker::run(server: $this->server);
|
||||
$this->server->team?->notify(new DockerCleanupSuccess($this->server, 'Docker cleanup job executed successfully, but no disk usage could be determined.'));
|
||||
$cleanup_log = CleanupDocker::run(server: $this->server);
|
||||
$message = 'Docker cleanup job executed successfully, but no disk usage could be determined.';
|
||||
|
||||
$this->execution_log->update([
|
||||
'status' => 'success',
|
||||
'message' => $message,
|
||||
'cleanup_log' => $cleanup_log,
|
||||
]);
|
||||
|
||||
$this->server->team?->notify(new DockerCleanupSuccess($this->server, $message));
|
||||
event(new DockerCleanupDone($this->execution_log));
|
||||
}
|
||||
|
||||
if ($this->usageBefore >= $this->server->settings->docker_cleanup_threshold) {
|
||||
CleanupDocker::run(server: $this->server);
|
||||
$cleanup_log = CleanupDocker::run(server: $this->server);
|
||||
$usageAfter = $this->server->getDiskUsage();
|
||||
$diskSaved = $this->usageBefore - $usageAfter;
|
||||
|
||||
if ($diskSaved > 0) {
|
||||
$this->server->team?->notify(new DockerCleanupSuccess($this->server, 'Saved '.$diskSaved.'% disk space. Disk usage before: '.$this->usageBefore.'%, Disk usage after: '.$usageAfter.'%.'));
|
||||
$message = 'Saved '.$diskSaved.'% disk space. Disk usage before: '.$this->usageBefore.'%, Disk usage after: '.$usageAfter.'%.';
|
||||
} else {
|
||||
$this->server->team?->notify(new DockerCleanupSuccess($this->server, 'Docker cleanup job executed successfully, but no disk space was saved. Disk usage before: '.$this->usageBefore.'%, Disk usage after: '.$usageAfter.'%.'));
|
||||
$message = 'Docker cleanup job executed successfully, but no disk space was saved. Disk usage before: '.$this->usageBefore.'%, Disk usage after: '.$usageAfter.'%.';
|
||||
}
|
||||
|
||||
$this->execution_log->update([
|
||||
'status' => 'success',
|
||||
'message' => $message,
|
||||
'cleanup_log' => $cleanup_log,
|
||||
]);
|
||||
|
||||
$this->server->team?->notify(new DockerCleanupSuccess($this->server, $message));
|
||||
event(new DockerCleanupDone($this->execution_log));
|
||||
} else {
|
||||
$this->server->team?->notify(new DockerCleanupSuccess($this->server, 'No cleanup needed for '.$this->server->name));
|
||||
$message = 'No cleanup needed for '.$this->server->name;
|
||||
|
||||
$this->execution_log->update([
|
||||
'status' => 'success',
|
||||
'message' => $message,
|
||||
]);
|
||||
|
||||
$this->server->team?->notify(new DockerCleanupSuccess($this->server, $message));
|
||||
event(new DockerCleanupDone($this->execution_log));
|
||||
}
|
||||
} catch (\Throwable $e) {
|
||||
if ($this->execution_log) {
|
||||
$this->execution_log->update([
|
||||
'status' => 'failed',
|
||||
'message' => $e->getMessage(),
|
||||
]);
|
||||
event(new DockerCleanupDone($this->execution_log));
|
||||
}
|
||||
$this->server->team?->notify(new DockerCleanupFailed($this->server, 'Docker cleanup job failed with the following error: '.$e->getMessage()));
|
||||
throw $e;
|
||||
} finally {
|
||||
if ($this->execution_log) {
|
||||
$this->execution_log->update([
|
||||
'finished_at' => Carbon::now()->toImmutable(),
|
||||
]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,6 +11,7 @@ use App\Models\Service;
|
||||
use App\Models\Team;
|
||||
use App\Notifications\ScheduledTask\TaskFailed;
|
||||
use App\Notifications\ScheduledTask\TaskSuccess;
|
||||
use Carbon\Carbon;
|
||||
use Illuminate\Bus\Queueable;
|
||||
use Illuminate\Contracts\Queue\ShouldQueue;
|
||||
use Illuminate\Foundation\Bus\Dispatchable;
|
||||
@@ -131,6 +132,11 @@ class ScheduledTaskJob implements ShouldQueue
|
||||
throw $e;
|
||||
} finally {
|
||||
ScheduledTaskDone::dispatch($this->team->id);
|
||||
if ($this->task_log) {
|
||||
$this->task_log->update([
|
||||
'finished_at' => Carbon::now()->toImmutable(),
|
||||
]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -117,29 +117,6 @@ class BackupExecutions extends Component
|
||||
return null;
|
||||
}
|
||||
|
||||
public function getServerTimezone()
|
||||
{
|
||||
$server = $this->server();
|
||||
if (! $server) {
|
||||
return 'UTC';
|
||||
}
|
||||
|
||||
return $server->settings->server_timezone;
|
||||
}
|
||||
|
||||
public function formatDateInServerTimezone($date)
|
||||
{
|
||||
$serverTimezone = $this->getServerTimezone();
|
||||
$dateObj = new \DateTime($date);
|
||||
try {
|
||||
$dateObj->setTimezone(new \DateTimeZone($serverTimezone));
|
||||
} catch (\Exception) {
|
||||
$dateObj->setTimezone(new \DateTimeZone('UTC'));
|
||||
}
|
||||
|
||||
return $dateObj->format('Y-m-d H:i:s T');
|
||||
}
|
||||
|
||||
public function render()
|
||||
{
|
||||
return view('livewire.project.database.backup-executions', [
|
||||
|
||||
@@ -141,17 +141,4 @@ class Executions extends Component
|
||||
|
||||
return $lines->count() > ($this->currentPage * $this->logsPerPage);
|
||||
}
|
||||
|
||||
public function formatDateInServerTimezone($date)
|
||||
{
|
||||
$serverTimezone = $this->serverTimezone;
|
||||
$dateObj = new \DateTime($date);
|
||||
try {
|
||||
$dateObj->setTimezone(new \DateTimeZone($serverTimezone));
|
||||
} catch (\Exception) {
|
||||
$dateObj->setTimezone(new \DateTimeZone('UTC'));
|
||||
}
|
||||
|
||||
return $dateObj->format('Y-m-d H:i:s T');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
|
||||
namespace App\Livewire\Server;
|
||||
|
||||
use App\Jobs\DockerCleanupJob;
|
||||
use App\Models\Server;
|
||||
use Livewire\Attributes\Validate;
|
||||
use Livewire\Component;
|
||||
@@ -19,21 +18,6 @@ class Advanced extends Component
|
||||
#[Validate(['integer', 'min:1', 'max:99'])]
|
||||
public int $serverDiskUsageNotificationThreshold = 50;
|
||||
|
||||
#[Validate(['string', 'required'])]
|
||||
public string $dockerCleanupFrequency = '*/10 * * * *';
|
||||
|
||||
#[Validate(['integer', 'min:1', 'max:99'])]
|
||||
public int $dockerCleanupThreshold = 10;
|
||||
|
||||
#[Validate('boolean')]
|
||||
public bool $forceDockerCleanup = false;
|
||||
|
||||
#[Validate('boolean')]
|
||||
public bool $deleteUnusedVolumes = false;
|
||||
|
||||
#[Validate('boolean')]
|
||||
public bool $deleteUnusedNetworks = false;
|
||||
|
||||
#[Validate(['integer', 'min:1'])]
|
||||
public int $concurrentBuilds = 1;
|
||||
|
||||
@@ -47,7 +31,7 @@ class Advanced extends Component
|
||||
$this->parameters = get_route_parameters();
|
||||
$this->syncData();
|
||||
} catch (\Throwable) {
|
||||
return redirect()->route('server.show');
|
||||
return redirect()->route('server.index');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -57,23 +41,13 @@ class Advanced extends Component
|
||||
$this->validate();
|
||||
$this->server->settings->concurrent_builds = $this->concurrentBuilds;
|
||||
$this->server->settings->dynamic_timeout = $this->dynamicTimeout;
|
||||
$this->server->settings->force_docker_cleanup = $this->forceDockerCleanup;
|
||||
$this->server->settings->docker_cleanup_frequency = $this->dockerCleanupFrequency;
|
||||
$this->server->settings->docker_cleanup_threshold = $this->dockerCleanupThreshold;
|
||||
$this->server->settings->server_disk_usage_notification_threshold = $this->serverDiskUsageNotificationThreshold;
|
||||
$this->server->settings->delete_unused_volumes = $this->deleteUnusedVolumes;
|
||||
$this->server->settings->delete_unused_networks = $this->deleteUnusedNetworks;
|
||||
$this->server->settings->server_disk_usage_check_frequency = $this->serverDiskUsageCheckFrequency;
|
||||
$this->server->settings->save();
|
||||
} else {
|
||||
$this->concurrentBuilds = $this->server->settings->concurrent_builds;
|
||||
$this->dynamicTimeout = $this->server->settings->dynamic_timeout;
|
||||
$this->forceDockerCleanup = $this->server->settings->force_docker_cleanup;
|
||||
$this->dockerCleanupFrequency = $this->server->settings->docker_cleanup_frequency;
|
||||
$this->dockerCleanupThreshold = $this->server->settings->docker_cleanup_threshold;
|
||||
$this->serverDiskUsageNotificationThreshold = $this->server->settings->server_disk_usage_notification_threshold;
|
||||
$this->deleteUnusedVolumes = $this->server->settings->delete_unused_volumes;
|
||||
$this->deleteUnusedNetworks = $this->server->settings->delete_unused_networks;
|
||||
$this->serverDiskUsageCheckFrequency = $this->server->settings->server_disk_usage_check_frequency;
|
||||
}
|
||||
}
|
||||
@@ -88,23 +62,9 @@ class Advanced extends Component
|
||||
}
|
||||
}
|
||||
|
||||
public function manualCleanup()
|
||||
{
|
||||
try {
|
||||
DockerCleanupJob::dispatch($this->server, true);
|
||||
$this->dispatch('success', 'Manual cleanup job started. Depending on the amount of data, this might take a while.');
|
||||
} catch (\Throwable $e) {
|
||||
return handleError($e, $this);
|
||||
}
|
||||
}
|
||||
|
||||
public function submit()
|
||||
{
|
||||
try {
|
||||
if (! validate_cron_expression($this->dockerCleanupFrequency)) {
|
||||
$this->dockerCleanupFrequency = $this->server->settings->getOriginal('docker_cleanup_frequency');
|
||||
throw new \Exception('Invalid Cron / Human expression for Docker Cleanup Frequency.');
|
||||
}
|
||||
if (! validate_cron_expression($this->serverDiskUsageCheckFrequency)) {
|
||||
$this->serverDiskUsageCheckFrequency = $this->server->settings->getOriginal('server_disk_usage_check_frequency');
|
||||
throw new \Exception('Invalid Cron / Human expression for Disk Usage Check Frequency.');
|
||||
|
||||
99
app/Livewire/Server/DockerCleanup.php
Normal file
99
app/Livewire/Server/DockerCleanup.php
Normal file
@@ -0,0 +1,99 @@
|
||||
<?php
|
||||
|
||||
namespace App\Livewire\Server;
|
||||
|
||||
use App\Jobs\DockerCleanupJob;
|
||||
use App\Models\Server;
|
||||
use Livewire\Attributes\Validate;
|
||||
use Livewire\Component;
|
||||
|
||||
class DockerCleanup extends Component
|
||||
{
|
||||
public Server $server;
|
||||
|
||||
public array $parameters = [];
|
||||
|
||||
#[Validate(['string', 'required'])]
|
||||
public string $dockerCleanupFrequency = '*/10 * * * *';
|
||||
|
||||
#[Validate(['integer', 'min:1', 'max:99'])]
|
||||
public int $dockerCleanupThreshold = 10;
|
||||
|
||||
#[Validate('boolean')]
|
||||
public bool $forceDockerCleanup = false;
|
||||
|
||||
#[Validate('boolean')]
|
||||
public bool $deleteUnusedVolumes = false;
|
||||
|
||||
#[Validate('boolean')]
|
||||
public bool $deleteUnusedNetworks = false;
|
||||
|
||||
public function mount(string $server_uuid)
|
||||
{
|
||||
try {
|
||||
$this->server = Server::ownedByCurrentTeam()->whereUuid($server_uuid)->firstOrFail();
|
||||
$this->parameters = get_route_parameters();
|
||||
$this->syncData();
|
||||
} catch (\Throwable) {
|
||||
return redirect()->route('server.index');
|
||||
}
|
||||
}
|
||||
|
||||
public function syncData(bool $toModel = false)
|
||||
{
|
||||
if ($toModel) {
|
||||
$this->validate();
|
||||
$this->server->settings->force_docker_cleanup = $this->forceDockerCleanup;
|
||||
$this->server->settings->docker_cleanup_frequency = $this->dockerCleanupFrequency;
|
||||
$this->server->settings->docker_cleanup_threshold = $this->dockerCleanupThreshold;
|
||||
$this->server->settings->delete_unused_volumes = $this->deleteUnusedVolumes;
|
||||
$this->server->settings->delete_unused_networks = $this->deleteUnusedNetworks;
|
||||
$this->server->settings->save();
|
||||
} else {
|
||||
$this->forceDockerCleanup = $this->server->settings->force_docker_cleanup;
|
||||
$this->dockerCleanupFrequency = $this->server->settings->docker_cleanup_frequency;
|
||||
$this->dockerCleanupThreshold = $this->server->settings->docker_cleanup_threshold;
|
||||
$this->deleteUnusedVolumes = $this->server->settings->delete_unused_volumes;
|
||||
$this->deleteUnusedNetworks = $this->server->settings->delete_unused_networks;
|
||||
}
|
||||
}
|
||||
|
||||
public function instantSave()
|
||||
{
|
||||
try {
|
||||
$this->syncData(true);
|
||||
$this->dispatch('success', 'Server updated.');
|
||||
} catch (\Throwable $e) {
|
||||
return handleError($e, $this);
|
||||
}
|
||||
}
|
||||
|
||||
public function manualCleanup()
|
||||
{
|
||||
try {
|
||||
DockerCleanupJob::dispatch($this->server, true);
|
||||
$this->dispatch('success', 'Manual cleanup job started. Depending on the amount of data, this might take a while.');
|
||||
} catch (\Throwable $e) {
|
||||
return handleError($e, $this);
|
||||
}
|
||||
}
|
||||
|
||||
public function submit()
|
||||
{
|
||||
try {
|
||||
if (! validate_cron_expression($this->dockerCleanupFrequency)) {
|
||||
$this->dockerCleanupFrequency = $this->server->settings->getOriginal('docker_cleanup_frequency');
|
||||
throw new \Exception('Invalid Cron / Human expression for Docker Cleanup Frequency.');
|
||||
}
|
||||
$this->syncData(true);
|
||||
$this->dispatch('success', 'Server updated.');
|
||||
} catch (\Throwable $e) {
|
||||
return handleError($e, $this);
|
||||
}
|
||||
}
|
||||
|
||||
public function render()
|
||||
{
|
||||
return view('livewire.server.docker-cleanup');
|
||||
}
|
||||
}
|
||||
132
app/Livewire/Server/DockerCleanupExecutions.php
Normal file
132
app/Livewire/Server/DockerCleanupExecutions.php
Normal file
@@ -0,0 +1,132 @@
|
||||
<?php
|
||||
|
||||
namespace App\Livewire\Server;
|
||||
|
||||
use App\Models\DockerCleanupExecution;
|
||||
use App\Models\Server;
|
||||
use Illuminate\Support\Collection;
|
||||
use Livewire\Component;
|
||||
|
||||
class DockerCleanupExecutions extends Component
|
||||
{
|
||||
public Server $server;
|
||||
|
||||
public Collection $executions;
|
||||
|
||||
public ?int $selectedKey = null;
|
||||
|
||||
public $selectedExecution = null;
|
||||
|
||||
public bool $isPollingActive = false;
|
||||
|
||||
public $currentPage = 1;
|
||||
|
||||
public $logsPerPage = 100;
|
||||
|
||||
public function getListeners()
|
||||
{
|
||||
$teamId = auth()->user()->currentTeam()->id;
|
||||
|
||||
return [
|
||||
"echo-private:team.{$teamId},DockerCleanupDone" => 'refreshExecutions',
|
||||
];
|
||||
}
|
||||
|
||||
public function mount(Server $server)
|
||||
{
|
||||
$this->server = $server;
|
||||
$this->refreshExecutions();
|
||||
}
|
||||
|
||||
public function refreshExecutions(): void
|
||||
{
|
||||
$this->executions = $this->server->dockerCleanupExecutions()
|
||||
->orderBy('created_at', 'desc')
|
||||
->take(20)
|
||||
->get();
|
||||
|
||||
if ($this->selectedKey) {
|
||||
$this->selectedExecution = DockerCleanupExecution::find($this->selectedKey);
|
||||
if ($this->selectedExecution && $this->selectedExecution->status !== 'running') {
|
||||
$this->isPollingActive = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function selectExecution($key): void
|
||||
{
|
||||
if ($key == $this->selectedKey) {
|
||||
$this->selectedKey = null;
|
||||
$this->selectedExecution = null;
|
||||
$this->currentPage = 1;
|
||||
$this->isPollingActive = false;
|
||||
|
||||
return;
|
||||
}
|
||||
$this->selectedKey = $key;
|
||||
$this->selectedExecution = DockerCleanupExecution::find($key);
|
||||
$this->currentPage = 1;
|
||||
|
||||
if ($this->selectedExecution && $this->selectedExecution->status === 'running') {
|
||||
$this->isPollingActive = true;
|
||||
}
|
||||
}
|
||||
|
||||
public function polling()
|
||||
{
|
||||
if ($this->selectedExecution && $this->isPollingActive) {
|
||||
$this->selectedExecution->refresh();
|
||||
if ($this->selectedExecution->status !== 'running') {
|
||||
$this->isPollingActive = false;
|
||||
}
|
||||
}
|
||||
$this->refreshExecutions();
|
||||
}
|
||||
|
||||
public function loadMoreLogs()
|
||||
{
|
||||
$this->currentPage++;
|
||||
}
|
||||
|
||||
public function getLogLinesProperty()
|
||||
{
|
||||
if (! $this->selectedExecution) {
|
||||
return collect();
|
||||
}
|
||||
|
||||
if (! $this->selectedExecution->message) {
|
||||
return collect(['Waiting for execution output...']);
|
||||
}
|
||||
|
||||
$lines = collect(explode("\n", $this->selectedExecution->message));
|
||||
|
||||
return $lines->take($this->currentPage * $this->logsPerPage);
|
||||
}
|
||||
|
||||
public function downloadLogs(int $executionId)
|
||||
{
|
||||
$execution = $this->executions->firstWhere('id', $executionId);
|
||||
if (! $execution) {
|
||||
return;
|
||||
}
|
||||
|
||||
return response()->streamDownload(function () use ($execution) {
|
||||
echo $execution->message;
|
||||
}, "docker-cleanup-{$execution->uuid}.log");
|
||||
}
|
||||
|
||||
public function hasMoreLogs()
|
||||
{
|
||||
if (! $this->selectedExecution || ! $this->selectedExecution->message) {
|
||||
return false;
|
||||
}
|
||||
$lines = collect(explode("\n", $this->selectedExecution->message));
|
||||
|
||||
return $lines->count() > ($this->currentPage * $this->logsPerPage);
|
||||
}
|
||||
|
||||
public function render()
|
||||
{
|
||||
return view('livewire.server.docker-cleanup-executions');
|
||||
}
|
||||
}
|
||||
@@ -81,7 +81,7 @@ class ApplicationDeploymentQueue extends Model
|
||||
return null;
|
||||
}
|
||||
|
||||
return str($this->commit_message)->trim()->limit(50)->value();
|
||||
return str($this->commit_message)->value();
|
||||
}
|
||||
|
||||
public function addLogEntry(string $message, string $type = 'stdout', bool $hidden = false)
|
||||
|
||||
15
app/Models/DockerCleanupExecution.php
Normal file
15
app/Models/DockerCleanupExecution.php
Normal file
@@ -0,0 +1,15 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||
|
||||
class DockerCleanupExecution extends BaseModel
|
||||
{
|
||||
protected $guarded = [];
|
||||
|
||||
public function server(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(Server::class);
|
||||
}
|
||||
}
|
||||
@@ -199,6 +199,11 @@ class Server extends BaseModel
|
||||
return $this->hasOne(ServerSetting::class);
|
||||
}
|
||||
|
||||
public function dockerCleanupExecutions()
|
||||
{
|
||||
return $this->hasMany(DockerCleanupExecution::class);
|
||||
}
|
||||
|
||||
public function proxySet()
|
||||
{
|
||||
return $this->proxyType() && $this->proxyType() !== 'NONE' && $this->isFunctional() && ! $this->isSwarmWorker() && ! $this->settings->is_build_server;
|
||||
|
||||
Reference in New Issue
Block a user