Merge branch 'next' into feat/monaco-editor

This commit is contained in:
Mahdi Taleghani
2024-06-23 22:50:25 +03:30
committed by GitHub
163 changed files with 2580 additions and 537 deletions

View File

@@ -12,7 +12,7 @@ use Livewire\Component;
class Index extends Component
{
protected $listeners = ['serverInstalled' => 'validateServer'];
protected $listeners = ['refreshBoardingIndex' => 'validateServer'];
public string $currentState = 'welcome';

View File

@@ -54,9 +54,9 @@ class DeploymentNavbar extends Component
public function cancel()
{
$kill_command = "docker rm -f {$this->application_deployment_queue->deployment_uuid}";
$server_id = $this->application_deployment_queue->server_id ?? $this->application->destination->server_id;
try {
$kill_command = "docker rm -f {$this->application_deployment_queue->deployment_uuid}";
$server_id = $this->application_deployment_queue->server_id ?? $this->application->destination->server_id;
$server = Server::find($server_id);
if ($this->application_deployment_queue->logs) {
$previous_logs = json_decode($this->application_deployment_queue->logs, associative: true, flags: JSON_THROW_ON_ERROR);
@@ -84,6 +84,7 @@ class DeploymentNavbar extends Component
'current_process_id' => null,
'status' => ApplicationDeploymentStatus::CANCELLED_BY_USER->value,
]);
next_after_cancel($server);
}
}
}

View File

@@ -347,7 +347,9 @@ class General extends Component
public function submit($showToaster = true)
{
try {
$this->set_redirect();
if ($this->application->isDirty('redirect')) {
$this->set_redirect();
}
$this->application->fqdn = str($this->application->fqdn)->replaceEnd(',', '')->trim();
$this->application->fqdn = str($this->application->fqdn)->replaceStart(',', '')->trim();
$this->application->fqdn = str($this->application->fqdn)->trim()->explode(',')->map(function ($domain) {

View File

@@ -45,7 +45,7 @@ class Heading extends Component
public function check_status($showNotification = false)
{
if ($this->application->destination->server->isFunctional()) {
GetContainersStatus::dispatch($this->application->destination->server);
GetContainersStatus::dispatch($this->application->destination->server)->onQueue('high');
// dispatch(new ContainerStatusJob($this->application->destination->server));
} else {
dispatch(new ServerStatusJob($this->application->destination->server));

View File

@@ -131,6 +131,12 @@ class Previews extends Component
}
}
public function add_and_deploy(int $pull_request_id, ?string $pull_request_html_url = null)
{
$this->add($pull_request_id, $pull_request_html_url);
$this->deploy($pull_request_id, $pull_request_html_url);
}
public function deploy(int $pull_request_id, ?string $pull_request_html_url = null)
{
try {
@@ -180,7 +186,7 @@ class Previews extends Component
instant_remote_process(["docker rm -f $name"], $this->application->destination->server, throwError: false);
}
}
GetContainersStatus::dispatchSync($this->application->destination->server);
GetContainersStatus::dispatchSync($this->application->destination->server)->onQueue('high');
$this->dispatch('reloadWindow');
} catch (\Throwable $e) {
return handleError($e, $this);

View File

@@ -12,7 +12,6 @@ use App\Actions\Database\StartPostgresql;
use App\Actions\Database\StartRedis;
use App\Actions\Database\StopDatabase;
use App\Actions\Docker\GetContainersStatus;
use App\Jobs\ContainerStatusJob;
use Livewire\Component;
class Heading extends Component

View File

@@ -25,7 +25,17 @@ class General extends Component
public ?string $db_url_public = null;
protected $listeners = ['refresh', 'save_init_script', 'delete_init_script'];
public function getListeners()
{
$userId = auth()->user()->id;
return [
"echo-private:user.{$userId},DatabaseStatusChanged" => 'database_stopped',
'refresh',
'save_init_script',
'delete_init_script',
];
}
protected $rules = [
'database.name' => 'required',
@@ -69,6 +79,11 @@ class General extends Component
$this->server = data_get($this->database, 'destination.server');
}
public function database_stopped()
{
$this->dispatch('success', 'Database proxy stopped. Database is no longer publicly accessible.');
}
public function instantSaveAdvanced()
{
try {

View File

@@ -128,8 +128,8 @@ class PublicGitRepository extends Component
) {
$this->repository_url = $this->repository_url.'.git';
}
if (str($this->repository_url)->contains('github.com')) {
$this->repository_url = str($this->repository_url)->before('.git')->value();
if (str($this->repository_url)->contains('github.com') && str($this->repository_url)->endsWith('.git')) {
$this->repository_url = str($this->repository_url)->beforeLast('.git')->value();
}
} catch (\Throwable $e) {
return handleError($e, $this);
@@ -140,7 +140,6 @@ class PublicGitRepository extends Component
$this->get_branch();
$this->selected_branch = $this->git_branch;
} catch (\Throwable $e) {
ray($e->getMessage());
if (! $this->branch_found && $this->git_branch == 'main') {
try {
$this->git_branch = 'master';

View File

@@ -176,10 +176,12 @@ class Select extends Component
return;
}
// if (count($this->servers) === 1) {
// $server = $this->servers->first();
// $this->setServer($server);
// }
if (count($this->servers) === 1) {
$server = $this->servers->first();
if ($server instanceof Server) {
$this->setServer($server);
}
}
if (! is_null($this->server)) {
$foundServer = $this->servers->where('id', $this->server->id)->first();
if ($foundServer) {
@@ -195,6 +197,13 @@ class Select extends Component
$this->server = $server;
$this->standaloneDockers = $server->standaloneDockers;
$this->swarmDockers = $server->swarmDockers;
$count = count($this->standaloneDockers) + count($this->swarmDockers);
if ($count === 1) {
$docker = $this->standaloneDockers->first() ?? $this->swarmDockers->first();
if ($docker) {
$this->setDestination($docker->uuid);
}
}
$this->current_step = 'destinations';
}

View File

@@ -0,0 +1,35 @@
<?php
namespace App\Livewire\Project\Resource;
use Illuminate\Database\Eloquent\Collection;
use Livewire\Component;
class EnvironmentSelect extends Component
{
public Collection $environments;
public string $project_uuid = '';
public string $selectedEnvironment = '';
public function mount()
{
$this->selectedEnvironment = request()->route('environment_name');
$this->project_uuid = request()->route('project_uuid');
}
public function updatedSelectedEnvironment($value)
{
if ($value === 'edit') {
return redirect()->route('project.show', [
'project_uuid' => $this->project_uuid,
]);
} else {
return redirect()->route('project.resource.index', [
'project_uuid' => $this->project_uuid,
'environment_name' => $value,
]);
}
}
}

View File

@@ -11,6 +11,8 @@ class EditCompose extends Component
public $serviceId;
protected $listeners = ['refreshEnvs' => 'mount'];
protected $rules = [
'service.docker_compose_raw' => 'required',
'service.docker_compose' => 'required',

View File

@@ -75,7 +75,6 @@ class StackForm extends Component
$this->service->parse();
$this->service->refresh();
$this->service->saveComposeConfigs();
$this->dispatch('refreshStacks');
$this->dispatch('refreshEnvs');
$this->dispatch('success', 'Service saved.');
} catch (\Throwable $e) {

View File

@@ -112,7 +112,6 @@ class All extends Component
$this->resource->environment_variables_preview()->whereNotIn('key', array_keys($variables))->delete();
} else {
$variables = parseEnvFormatToArray($this->variables);
ray($variables, $this->variables);
$this->resource->environment_variables()->whereNotIn('key', array_keys($variables))->delete();
}
foreach ($variables as $key => $variable) {

View File

@@ -64,7 +64,7 @@ class Logs extends Component
return;
$server = data_get($this->resource, 'destination.server');
if ($server->isFunctional()) {
$this->cpu = $server->getMetrics();
$this->cpu = $server->getCpuMetrics();
}
}

View File

@@ -0,0 +1,64 @@
<?php
namespace App\Livewire\Project\Shared;
use Livewire\Component;
class Metrics extends Component
{
public $resource;
public $chartId = 'container-cpu';
public $data;
public $categories;
public int $interval = 5;
public bool $poll = true;
public function pollData()
{
if ($this->poll || $this->interval <= 10) {
$this->loadData();
if ($this->interval > 10) {
$this->poll = false;
}
}
}
public function loadData()
{
try {
$metrics = $this->resource->getMetrics($this->interval);
$cpuMetrics = collect($metrics)->map(function ($metric) {
return [$metric[0], $metric[1]];
});
$memoryMetrics = collect($metrics)->map(function ($metric) {
return [$metric[0], $metric[2]];
});
$this->dispatch("refreshChartData-{$this->chartId}-cpu", [
'seriesData' => $cpuMetrics,
]);
$this->dispatch("refreshChartData-{$this->chartId}-memory", [
'seriesData' => $memoryMetrics,
]);
} catch (\Throwable $e) {
return handleError($e, $this);
}
}
public function setInterval()
{
if ($this->interval <= 10) {
$this->poll = true;
}
$this->loadData();
}
public function render()
{
return view('livewire.project.shared.metrics');
}
}

View File

@@ -9,6 +9,8 @@ class Show extends Component
{
public Project $project;
public $environments;
public function mount()
{
$projectUuid = request()->route('project_uuid');
@@ -18,7 +20,8 @@ class Show extends Component
if (! $project) {
return redirect()->route('dashboard');
}
$project->load(['environments']);
$this->environments = $project->environments->sortBy('created_at');
$this->project = $project;
}

View File

@@ -0,0 +1,62 @@
<?php
namespace App\Livewire\Server;
use App\Models\Server;
use Livewire\Component;
class Charts extends Component
{
public Server $server;
public $chartId = 'server';
public $data;
public $categories;
public int $interval = 5;
public bool $poll = true;
public function pollData()
{
if ($this->poll || $this->interval <= 10) {
$this->loadData();
if ($this->interval > 10) {
$this->poll = false;
}
}
}
public function loadData()
{
try {
$cpuMetrics = $this->server->getCpuMetrics($this->interval);
$memoryMetrics = $this->server->getMemoryMetrics($this->interval);
$cpuMetrics = collect($cpuMetrics)->map(function ($metric) {
return [$metric[0], $metric[1]];
});
$memoryMetrics = collect($memoryMetrics)->map(function ($metric) {
return [$metric[0], $metric[1]];
});
$this->dispatch("refreshChartData-{$this->chartId}-cpu", [
'seriesData' => $cpuMetrics,
]);
$this->dispatch("refreshChartData-{$this->chartId}-memory", [
'seriesData' => $memoryMetrics,
]);
} catch (\Throwable $e) {
return handleError($e, $this);
}
}
public function setInterval()
{
if ($this->interval <= 10) {
$this->poll = true;
}
$this->loadData();
}
}

View File

@@ -21,7 +21,7 @@ class ConfigureCloudflareTunnels extends Component
$server->settings->is_cloudflare_tunnel = true;
$server->settings->save();
$this->dispatch('success', 'Cloudflare Tunnels configured successfully.');
$this->dispatch('serverInstalled');
$this->dispatch('refreshServerShow');
} catch (\Throwable $e) {
return handleError($e, $this);
}
@@ -37,7 +37,7 @@ class ConfigureCloudflareTunnels extends Component
$server->save();
$server->settings->save();
$this->dispatch('success', 'Cloudflare Tunnels configured successfully.');
$this->dispatch('serverInstalled');
$this->dispatch('refreshServerShow');
} catch (\Throwable $e) {
return handleError($e, $this);
}

View File

@@ -2,6 +2,9 @@
namespace App\Livewire\Server;
use App\Actions\Server\StartSentinel;
use App\Actions\Server\StopSentinel;
use App\Jobs\PullSentinelImageJob;
use App\Models\Server;
use Livewire\Component;
@@ -36,7 +39,12 @@ class Form extends Component
'server.settings.is_build_server' => 'required|boolean',
'server.settings.concurrent_builds' => 'required|integer|min:1',
'server.settings.dynamic_timeout' => 'required|integer|min:1',
'server.settings.is_metrics_enabled' => 'required|boolean',
'server.settings.metrics_token' => 'required',
'server.settings.metrics_refresh_rate_seconds' => 'required|integer|min:1',
'server.settings.metrics_history_days' => 'required|integer|min:1',
'wildcard_domain' => 'nullable|url',
'server.settings.is_server_api_enabled' => 'required|boolean',
];
protected $validationAttributes = [
@@ -52,7 +60,11 @@ class Form extends Component
'server.settings.is_build_server' => 'Build Server',
'server.settings.concurrent_builds' => 'Concurrent Builds',
'server.settings.dynamic_timeout' => 'Dynamic Timeout',
'server.settings.is_metrics_enabled' => 'Metrics',
'server.settings.metrics_token' => 'Metrics Token',
'server.settings.metrics_refresh_rate_seconds' => 'Metrics Interval',
'server.settings.metrics_history_days' => 'Metrics History',
'server.settings.is_server_api_enabled' => 'Server API',
];
public function mount()
@@ -69,18 +81,59 @@ class Form extends Component
public function updatedServerSettingsIsBuildServer()
{
$this->dispatch('serverInstalled');
$this->dispatch('refreshServerShow');
$this->dispatch('serverRefresh');
$this->dispatch('proxyStatusUpdated');
}
public function checkPortForServerApi()
{
try {
if ($this->server->settings->is_server_api_enabled === true) {
$this->server->checkServerApi();
$this->dispatch('success', 'Server API is reachable.');
}
} catch (\Throwable $e) {
return handleError($e, $this);
}
}
public function instantSave()
{
try {
refresh_server_connection($this->server->privateKey);
$this->validateServer(false);
$this->server->settings->save();
$this->server->save();
$this->dispatch('success', 'Server updated.');
$this->dispatch('refreshServerShow');
if ($this->server->isSentinelEnabled()) {
PullSentinelImageJob::dispatchSync($this->server);
ray('Sentinel is enabled');
if ($this->server->settings->isDirty('is_metrics_enabled')) {
$this->dispatch('reloadWindow');
}
if ($this->server->settings->isDirty('is_server_api_enabled') && $this->server->settings->is_server_api_enabled === true) {
ray('Starting sentinel');
}
} else {
ray('Sentinel is not enabled');
StopSentinel::dispatch($this->server);
}
// $this->checkPortForServerApi();
} catch (\Throwable $e) {
return handleError($e, $this);
}
}
public function restartSentinel()
{
try {
$version = get_latest_sentinel_version();
StartSentinel::run($this->server, $version, true);
$this->dispatch('success', 'Sentinel restarted.');
} catch (\Throwable $e) {
return handleError($e, $this);
}

View File

@@ -14,7 +14,7 @@ class Show extends Component
public $parameters = [];
protected $listeners = ['serverInstalled' => '$refresh'];
protected $listeners = ['refreshServerShow' => '$refresh'];
public function mount()
{

View File

@@ -143,7 +143,8 @@ class ValidateAndInstall extends Component
} else {
$this->docker_version = $this->server->validateDockerEngineVersion();
if ($this->docker_version) {
$this->dispatch('serverInstalled');
$this->dispatch('refreshServerShow');
$this->dispatch('refreshBoardingIndex');
$this->dispatch('success', 'Server validated.');
} else {
$this->error = 'Docker Engine version is not 22+. Please install Docker manually before continuing: <a target="_blank" class="underline" href="https://docs.docker.com/engine/install/#server">documentation</a>.';