From 6b302ab78611d3867c3f9a9622db09e84c6cce2f Mon Sep 17 00:00:00 2001 From: Andras Bacsai Date: Wed, 18 Oct 2023 09:03:14 +0200 Subject: [PATCH 01/22] Add restarting indicator to resources --- config/sentry.php | 2 +- config/version.php | 2 +- resources/views/project/resources.blade.php | 12 ++++++++---- versions.json | 2 +- 4 files changed, 11 insertions(+), 7 deletions(-) diff --git a/config/sentry.php b/config/sentry.php index 4a096757f..263e642b1 100644 --- a/config/sentry.php +++ b/config/sentry.php @@ -7,7 +7,7 @@ return [ // The release version of your application // Example with dynamic git hash: trim(exec('git --git-dir ' . base_path('.git') . ' log --pretty="%h" -n1 HEAD')) - 'release' => '4.0.0-beta.92', + 'release' => '4.0.0-beta.93', // When left empty or `null` the Laravel environment will be used 'environment' => config('app.env'), diff --git a/config/version.php b/config/version.php index d889b7a6c..1b3ce03c5 100644 --- a/config/version.php +++ b/config/version.php @@ -1,3 +1,3 @@ @if (Str::of(data_get($application, 'status'))->startsWith('running')) -
+
@elseif (Str::of(data_get($application, 'status'))->startsWith('exited'))
+ @elseif (Str::of(data_get($application, 'status'))->startsWith('restarting')) +
@endif @endforeach @@ -60,9 +62,11 @@
{{ $database->description }}
@if (Str::of(data_get($database, 'status'))->startsWith('running')) -
+
@elseif (Str::of(data_get($database, 'status'))->startsWith('exited'))
+ @elseif (Str::of(data_get($database, 'status'))->startsWith('restaring')) +
@endif @endforeach @@ -74,9 +78,9 @@
{{ $service->description }}
@if (Str::of(serviceStatus($service))->startsWith('running')) -
+
@elseif (Str::of(serviceStatus($service))->startsWith('degraded')) -
+
@elseif (Str::of(serviceStatus($service))->startsWith('exited'))
@endif diff --git a/versions.json b/versions.json index a78a28277..c4f05a469 100644 --- a/versions.json +++ b/versions.json @@ -4,7 +4,7 @@ "version": "3.12.36" }, "v4": { - "version": "4.0.0-beta.92" + "version": "4.0.0-beta.93" } } } From 0b3cde44c3001460f07e14d3c02a9ccbf1f0735b Mon Sep 17 00:00:00 2001 From: Andras Bacsai Date: Wed, 18 Oct 2023 10:32:08 +0200 Subject: [PATCH 02/22] feat: able to customize docker labels on applications --- .../Livewire/Project/Application/General.php | 74 +++++++++++++------ app/Jobs/ApplicationDeploymentJob.php | 9 ++- app/Models/Service.php | 4 +- bootstrap/helpers/docker.php | 12 +-- ...9_add_custom_labels_applications_table.php | 28 +++++++ .../project/application/general.blade.php | 6 ++ 6 files changed, 101 insertions(+), 32 deletions(-) create mode 100644 database/migrations/2023_10_18_072519_add_custom_labels_applications_table.php diff --git a/app/Http/Livewire/Project/Application/General.php b/app/Http/Livewire/Project/Application/General.php index dc3bd8db6..810c7cc42 100644 --- a/app/Http/Livewire/Project/Application/General.php +++ b/app/Http/Livewire/Project/Application/General.php @@ -3,12 +3,9 @@ namespace App\Http\Livewire\Project\Application; use App\Models\Application; -use App\Models\InstanceSettings; use Illuminate\Support\Collection; use Illuminate\Support\Str; use Livewire\Component; -use Spatie\Url\Url; -use Symfony\Component\Yaml\Yaml; class General extends Component { @@ -23,6 +20,9 @@ class General extends Component public ?string $git_commit_sha = null; public string $build_pack; + public $customLabels; + public bool $labelsChanged = false; + public bool $is_static; public bool $is_git_submodules_enabled; public bool $is_git_lfs_enabled; @@ -52,6 +52,7 @@ class General extends Component 'application.docker_registry_image_name' => 'nullable', 'application.docker_registry_image_tag' => 'nullable', 'application.dockerfile_location' => 'nullable', + 'application.custom_labels' => 'nullable', ]; protected $validationAttributes = [ 'application.name' => 'name', @@ -73,16 +74,43 @@ class General extends Component 'application.docker_registry_image_name' => 'Docker registry image name', 'application.docker_registry_image_tag' => 'Docker registry image tag', 'application.dockerfile_location' => 'Dockerfile location', - + 'application.custom_labels' => 'Custom labels', ]; - public function updatedApplicationBuildPack(){ + public function mount() + { + if (is_null(data_get($this->application, 'custom_labels'))) { + $this->customLabels = str(implode(",", generateLabelsApplication($this->application)))->replace(',', "\n"); + } else { + $this->customLabels = str($this->application->custom_labels)->replace(',', "\n"); + } + if (data_get($this->application, 'settings')) { + $this->is_static = $this->application->settings->is_static; + $this->is_git_submodules_enabled = $this->application->settings->is_git_submodules_enabled; + $this->is_git_lfs_enabled = $this->application->settings->is_git_lfs_enabled; + $this->is_debug_enabled = $this->application->settings->is_debug_enabled; + $this->is_preview_deployments_enabled = $this->application->settings->is_preview_deployments_enabled; + $this->is_auto_deploy_enabled = $this->application->settings->is_auto_deploy_enabled; + $this->is_force_https_enabled = $this->application->settings->is_force_https_enabled; + } + $this->checkLabelUpdates(); + } + public function updatedApplicationBuildPack() + { if ($this->application->build_pack !== 'nixpacks') { $this->application->settings->is_static = $this->is_static = false; $this->application->settings->save(); } $this->submit(); } + public function checkLabelUpdates() + { + if (md5($this->application->custom_labels) !== md5(implode(",", generateLabelsApplication($this->application)))) { + $this->labelsChanged = true; + } else { + $this->labelsChanged = false; + } + } public function instantSave() { // @TODO: find another way - if possible @@ -102,37 +130,35 @@ class General extends Component $this->application->save(); $this->application->refresh(); $this->emit('success', 'Application settings updated!'); + $this->checkLabelUpdates(); } - public function getWildcardDomain() { + public function getWildcardDomain() + { $server = data_get($this->application, 'destination.server'); if ($server) { $fqdn = generateFqdn($server, $this->application->uuid); - ray($fqdn); $this->application->fqdn = $fqdn; $this->application->save(); $this->emit('success', 'Application settings updated!'); } - } - public function mount() + public function resetDefaultLabels($showToaster = true) { - if (data_get($this->application,'settings')) { - $this->is_static = $this->application->settings->is_static; - $this->is_git_submodules_enabled = $this->application->settings->is_git_submodules_enabled; - $this->is_git_lfs_enabled = $this->application->settings->is_git_lfs_enabled; - $this->is_debug_enabled = $this->application->settings->is_debug_enabled; - $this->is_preview_deployments_enabled = $this->application->settings->is_preview_deployments_enabled; - $this->is_auto_deploy_enabled = $this->application->settings->is_auto_deploy_enabled; - $this->is_force_https_enabled = $this->application->settings->is_force_https_enabled; - } + $this->customLabels = str(implode(",", generateLabelsApplication($this->application)))->replace(',', "\n"); + $this->submit($showToaster); } - public function submit() + public function updatedApplicationFqdn() + { + $this->resetDefaultLabels(false); + $this->emit('success', 'Labels reseted to default!'); + } + public function submit($showToaster = true) { try { $this->validate(); - if (data_get($this->application,'build_pack') === 'dockerimage') { + if (data_get($this->application, 'build_pack') === 'dockerimage') { $this->validate([ 'application.docker_registry_image_name' => 'required', 'application.docker_registry_image_tag' => 'required', @@ -156,10 +182,16 @@ class General extends Component if ($this->application->publish_directory && $this->application->publish_directory !== '/') { $this->application->publish_directory = rtrim($this->application->publish_directory, '/'); } + if (gettype($this->customLabels) === 'string') { + $this->customLabels = str($this->customLabels)->replace(',', "\n"); + } + $this->application->custom_labels = $this->customLabels->explode("\n")->implode(','); $this->application->save(); - $this->emit('success', 'Application settings updated!'); + $showToaster && $this->emit('success', 'Application settings updated!'); } catch (\Throwable $e) { return handleError($e, $this); + } finally { + $this->checkLabelUpdates(); } } } diff --git a/app/Jobs/ApplicationDeploymentJob.php b/app/Jobs/ApplicationDeploymentJob.php index 09e7c510d..636adb35a 100644 --- a/app/Jobs/ApplicationDeploymentJob.php +++ b/app/Jobs/ApplicationDeploymentJob.php @@ -54,7 +54,7 @@ class ApplicationDeploymentJob implements ShouldQueue, ShouldBeEncrypted private ApplicationPreview|null $preview = null; private string $container_name; - private string|null $currently_running_container_name = null; + private ?string $currently_running_container_name = null; private string $basedir; private string $workdir; private ?string $build_pack = null; @@ -166,7 +166,6 @@ class ApplicationDeploymentJob implements ShouldQueue, ShouldBeEncrypted // Get user home directory $this->serverUserHomeDir = instant_remote_process(["echo \$HOME"], $this->server); - ray("test -f {$this->serverUserHomeDir}/.docker/config.json && echo 'OK' || echo 'NOK'"); $this->dockerConfigFileExists = instant_remote_process(["test -f {$this->serverUserHomeDir}/.docker/config.json && echo 'OK' || echo 'NOK'"], $this->server); try { if ($this->application->dockerfile) { @@ -650,6 +649,10 @@ class ApplicationDeploymentJob implements ShouldQueue, ShouldBeEncrypted $volume_names = $this->generate_local_persistent_volumes_only_volume_names(); $environment_variables = $this->generate_environment_variables($ports); + $labels = generateLabelsApplication($this->application, $this->preview); + if (data_get($this->application, 'custom_labels')) { + $labels = str($this->application->custom_labels)->explode(',')->toArray(); + } $docker_compose = [ 'version' => '3.8', 'services' => [ @@ -658,7 +661,7 @@ class ApplicationDeploymentJob implements ShouldQueue, ShouldBeEncrypted 'container_name' => $this->container_name, 'restart' => RESTART_MODE, 'environment' => $environment_variables, - 'labels' => generateLabelsApplication($this->application, $this->preview, $ports), + 'labels' => $labels, 'expose' => $ports, 'networks' => [ $this->destination->network, diff --git a/app/Models/Service.php b/app/Models/Service.php index 4fbb6a1f7..95fe826fb 100644 --- a/app/Models/Service.php +++ b/app/Models/Service.php @@ -538,7 +538,7 @@ class Service extends BaseModel $serviceLabels = $serviceLabels->merge($defaultLabels); if (!$isDatabase && $fqdns->count() > 0) { if ($fqdns) { - $serviceLabels = $serviceLabels->merge(fqdnLabelsForTraefik($fqdns, true)); + $serviceLabels = $serviceLabels->merge(fqdnLabelsForTraefik($this->uuid, $fqdns, true)); } } data_set($service, 'labels', $serviceLabels->toArray()); @@ -568,7 +568,7 @@ class Service extends BaseModel 'networks' => $topLevelNetworks->toArray(), ]; $this->docker_compose_raw = Yaml::dump($yaml, 10, 2); - $this->docker_compose = Yaml::dump($finalServices, 10, 2); + $this->docker_compose = Yaml::dump($finalServices, 10, 2); $this->save(); $this->saveComposeConfigs(); return collect([]); diff --git a/bootstrap/helpers/docker.php b/bootstrap/helpers/docker.php index adf1761f1..dfa4c1788 100644 --- a/bootstrap/helpers/docker.php +++ b/bootstrap/helpers/docker.php @@ -147,12 +147,11 @@ function defaultLabels($id, $name, $pull_request_id = 0, string $type = 'applica } return $labels; } -function fqdnLabelsForTraefik(Collection $domains, bool $is_force_https_enabled, $onlyPort = null) +function fqdnLabelsForTraefik($uuid, Collection $domains, bool $is_force_https_enabled, $onlyPort = null) { $labels = collect([]); $labels->push('traefik.enable=true'); foreach ($domains as $domain) { - $uuid = (string)new Cuid2(7); $url = Url::fromString($domain); $host = $url->getHost(); $path = $url->getPath(); @@ -205,20 +204,21 @@ function fqdnLabelsForTraefik(Collection $domains, bool $is_force_https_enabled, return $labels; } -function generateLabelsApplication(Application $application, ?ApplicationPreview $preview = null, $ports): array +function generateLabelsApplication(Application $application, ?ApplicationPreview $preview = null): array { + $ports = $application->settings->is_static ? [80] : $application->ports_exposes_array; $onlyPort = null; if (count($ports) === 1) { $onlyPort = $ports[0]; } $pull_request_id = data_get($preview, 'pull_request_id', 0); - $container_name = generateApplicationContainerName($application, $pull_request_id); + // $container_name = generateApplicationContainerName($application, $pull_request_id); $appId = $application->id; if ($pull_request_id !== 0 && $pull_request_id !== null) { $appId = $appId . '-pr-' . $pull_request_id; } $labels = collect([]); - $labels = $labels->merge(defaultLabels($appId, $container_name, $pull_request_id)); + $labels = $labels->merge(defaultLabels($appId, $application->uuid, $pull_request_id)); if ($application->fqdn) { if ($pull_request_id !== 0) { $domains = Str::of(data_get($preview, 'fqdn'))->explode(','); @@ -226,7 +226,7 @@ function generateLabelsApplication(Application $application, ?ApplicationPreview $domains = Str::of(data_get($application, 'fqdn'))->explode(','); } // Add Traefik labels no matter which proxy is selected - $labels = $labels->merge(fqdnLabelsForTraefik($domains, $application->settings->is_force_https_enabled,$onlyPort)); + $labels = $labels->merge(fqdnLabelsForTraefik($application->uuid, $domains, $application->settings->is_force_https_enabled, $onlyPort)); } return $labels->all(); } diff --git a/database/migrations/2023_10_18_072519_add_custom_labels_applications_table.php b/database/migrations/2023_10_18_072519_add_custom_labels_applications_table.php new file mode 100644 index 000000000..f993e35ee --- /dev/null +++ b/database/migrations/2023_10_18_072519_add_custom_labels_applications_table.php @@ -0,0 +1,28 @@ +text('custom_labels')->nullable(); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::table('applications', function (Blueprint $table) { + $table->dropColumn('custom_labels'); + }); + } +}; diff --git a/resources/views/livewire/project/application/general.blade.php b/resources/views/livewire/project/application/general.blade.php index 2962cdaa9..b554b8ff5 100644 --- a/resources/views/livewire/project/application/general.blade.php +++ b/resources/views/livewire/project/application/general.blade.php @@ -93,6 +93,12 @@ + @if ($labelsChanged) + + @else + + @endif + Reset to Default Labels

Advanced

From a61a86dc3b343683b88d0fce1db8546429372a6a Mon Sep 17 00:00:00 2001 From: Andras Bacsai Date: Wed, 18 Oct 2023 11:20:40 +0200 Subject: [PATCH 03/22] feat: show if config is not applied --- .../Livewire/Project/Application/General.php | 4 +++ app/Jobs/ApplicationDeploymentJob.php | 12 ++++++--- app/Models/Application.php | 27 +++++++++++++++++++ .../project/application/general.blade.php | 7 +++-- 4 files changed, 45 insertions(+), 5 deletions(-) diff --git a/app/Http/Livewire/Project/Application/General.php b/app/Http/Livewire/Project/Application/General.php index 810c7cc42..71d75a7c5 100644 --- a/app/Http/Livewire/Project/Application/General.php +++ b/app/Http/Livewire/Project/Application/General.php @@ -22,6 +22,7 @@ class General extends Component public $customLabels; public bool $labelsChanged = false; + public bool $isConfigurationChanged = false; public bool $is_static; public bool $is_git_submodules_enabled; @@ -79,6 +80,7 @@ class General extends Component public function mount() { + $this->isConfigurationChanged = $this->application->isConfigurationChanged(); if (is_null(data_get($this->application, 'custom_labels'))) { $this->customLabels = str(implode(",", generateLabelsApplication($this->application)))->replace(',', "\n"); } else { @@ -131,6 +133,7 @@ class General extends Component $this->application->refresh(); $this->emit('success', 'Application settings updated!'); $this->checkLabelUpdates(); + $this->isConfigurationChanged = $this->application->isConfigurationChanged(); } public function getWildcardDomain() @@ -192,6 +195,7 @@ class General extends Component return handleError($e, $this); } finally { $this->checkLabelUpdates(); + $this->isConfigurationChanged = $this->application->isConfigurationChanged(); } } } diff --git a/app/Jobs/ApplicationDeploymentJob.php b/app/Jobs/ApplicationDeploymentJob.php index 636adb35a..a6d6050bf 100644 --- a/app/Jobs/ApplicationDeploymentJob.php +++ b/app/Jobs/ApplicationDeploymentJob.php @@ -78,7 +78,7 @@ class ApplicationDeploymentJob implements ShouldQueue, ShouldBeEncrypted public $tries = 1; public function __construct(int $application_deployment_queue_id) { - ray()->clearScreen(); + // ray()->clearScreen(); $this->application_deployment_queue = ApplicationDeploymentQueue::find($application_deployment_queue_id); $this->log_model = $this->application_deployment_queue; $this->application = Application::find($this->application_deployment_queue->application_id); @@ -185,6 +185,7 @@ class ApplicationDeploymentJob implements ShouldQueue, ShouldBeEncrypted dispatch(new ContainerStatusJob($this->server)); } $this->next(ApplicationDeploymentStatus::FINISHED->value); + $this->application->isConfigurationChanged(true); } catch (Exception $e) { ray($e); $this->fail($e); @@ -353,14 +354,19 @@ class ApplicationDeploymentJob implements ShouldQueue, ShouldBeEncrypted $this->execute_remote_command([ "docker images -q {$this->production_image_name} 2>/dev/null", "hidden" => true, "save" => "local_image_found" ]); - if (Str::of($this->saved_outputs->get('local_image_found'))->isNotEmpty()) { + if (Str::of($this->saved_outputs->get('local_image_found'))->isNotEmpty() && !$this->application->isConfigurationChanged()) { $this->execute_remote_command([ - "echo 'Docker Image found locally with the same Git Commit SHA {$this->application->uuid}:{$this->commit}. Build step skipped...'" + "echo 'No configuration changed & Docker Image found locally with the same Git Commit SHA {$this->application->uuid}:{$this->commit}. Build step skipped.'", ]); $this->generate_compose_file(); $this->rolling_update(); return; } + if ($this->application->isConfigurationChanged()) { + $this->execute_remote_command([ + "echo 'Configuration changed. Rebuilding image.'", + ]); + } } $this->cleanup_git(); $this->generate_nixpacks_confs(); diff --git a/app/Models/Application.php b/app/Models/Application.php index e5bf9db07..2e6c2814d 100644 --- a/app/Models/Application.php +++ b/app/Models/Application.php @@ -277,4 +277,31 @@ class Application extends BaseModel } return false; } + public function isConfigurationChanged($save = false) + { + $newConfigHash = $this->fqdn . $this->git_repository . $this->git_branch . $this->git_commit_sha . $this->build_pack . $this->static_image . $this->install_command . $this->build_command . $this->start_command . $this->port_exposes . $this->port_mappings . $this->base_directory . $this->publish_directory . $this->health_check_path . $this->health_check_port . $this->health_check_host . $this->health_check_method . $this->health_check_return_code . $this->health_check_scheme . $this->health_check_response_text . $this->health_check_interval . $this->health_check_timeout . $this->health_check_retries . $this->health_check_start_period . $this->health_check_enabled . $this->limits_memory . $this->limits_swap . $this->limits_swappiness . $this->limits_reservation . $this->limits_cpus . $this->limits_cpuset . $this->limits_cpu_shares . $this->dockerfile . $this->dockerfile_location . $this->custom_labels; + if ($this->pull_request_id === 0) { + $newConfigHash .= json_encode($this->environment_variables->all()); + } else { + $newConfigHash .= json_encode($this->environment_variables_preview->all()); + } + $newConfigHash = md5($newConfigHash); + $oldConfigHash = data_get($this, 'config_hash'); + if ($oldConfigHash === null) { + if ($save) { + $this->config_hash = $newConfigHash; + $this->save(); + } + return true; + } + if ($oldConfigHash === $newConfigHash) { + return false; + } else { + if ($save) { + $this->config_hash = $newConfigHash; + $this->save(); + } + return true; + } + } } diff --git a/resources/views/livewire/project/application/general.blade.php b/resources/views/livewire/project/application/general.blade.php index b554b8ff5..71a63248b 100644 --- a/resources/views/livewire/project/application/general.blade.php +++ b/resources/views/livewire/project/application/general.blade.php @@ -5,8 +5,12 @@ Save + @if ($isConfigurationChanged) +
Configuration not applied to the running application. You need to + redeploy.
+ @endif
-
General configuration for your application.
+
General configuration for your application.
@@ -81,7 +85,6 @@ @if ($application->dockerfile) @endif -

Network

@if ($application->settings->is_static) From b101fbacd49d24783e310376298c2aad349692d0 Mon Sep 17 00:00:00 2001 From: Andras Bacsai Date: Wed, 18 Oct 2023 11:22:56 +0200 Subject: [PATCH 04/22] fix: do not show configuration changed if config_hash is null --- resources/views/livewire/project/application/general.blade.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resources/views/livewire/project/application/general.blade.php b/resources/views/livewire/project/application/general.blade.php index 71a63248b..a2e90b015 100644 --- a/resources/views/livewire/project/application/general.blade.php +++ b/resources/views/livewire/project/application/general.blade.php @@ -5,7 +5,7 @@ Save - @if ($isConfigurationChanged) + @if ($isConfigurationChanged && !is_null($application->config_hash))
Configuration not applied to the running application. You need to redeploy.
@endif From 7678cd47df305bdb6f1500528ce5672256e5d987 Mon Sep 17 00:00:00 2001 From: Andras Bacsai Date: Wed, 18 Oct 2023 11:26:01 +0200 Subject: [PATCH 05/22] fix: add config_hash if its null (old deployments) --- app/Http/Livewire/Project/Application/General.php | 3 +++ resources/views/livewire/project/application/general.blade.php | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/app/Http/Livewire/Project/Application/General.php b/app/Http/Livewire/Project/Application/General.php index 71d75a7c5..c99650912 100644 --- a/app/Http/Livewire/Project/Application/General.php +++ b/app/Http/Livewire/Project/Application/General.php @@ -80,6 +80,9 @@ class General extends Component public function mount() { + if (str($this->application->status)->startsWith('running') && is_null($this->application->config_hash)) { + $this->application->isConfigurationChanged(true); + } $this->isConfigurationChanged = $this->application->isConfigurationChanged(); if (is_null(data_get($this->application, 'custom_labels'))) { $this->customLabels = str(implode(",", generateLabelsApplication($this->application)))->replace(',', "\n"); diff --git a/resources/views/livewire/project/application/general.blade.php b/resources/views/livewire/project/application/general.blade.php index a2e90b015..79948bd6a 100644 --- a/resources/views/livewire/project/application/general.blade.php +++ b/resources/views/livewire/project/application/general.blade.php @@ -101,7 +101,7 @@ @else @endif - Reset to Default Labels + Reset to Coolify Generated Labels

Advanced

From dddbe40bbe0da5f3719ecbe3eb0712ce0e7f280d Mon Sep 17 00:00:00 2001 From: Andras Bacsai Date: Wed, 18 Oct 2023 11:35:36 +0200 Subject: [PATCH 06/22] fix dashboard ui on small screens --- config/sentry.php | 2 +- config/version.php | 2 +- resources/views/livewire/dashboard.blade.php | 4 ++-- versions.json | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/config/sentry.php b/config/sentry.php index 263e642b1..61c18786f 100644 --- a/config/sentry.php +++ b/config/sentry.php @@ -7,7 +7,7 @@ return [ // The release version of your application // Example with dynamic git hash: trim(exec('git --git-dir ' . base_path('.git') . ' log --pretty="%h" -n1 HEAD')) - 'release' => '4.0.0-beta.93', + 'release' => '4.0.0-beta.94', // When left empty or `null` the Laravel environment will be used 'environment' => config('app.env'), diff --git a/config/version.php b/config/version.php index 1b3ce03c5..4daf3b070 100644 --- a/config/version.php +++ b/config/version.php @@ -1,3 +1,3 @@ count() === 1)
@else -
+
@endif @foreach ($projects as $project)
description }}
@endif - + New Resource diff --git a/versions.json b/versions.json index c4f05a469..2c40f0e11 100644 --- a/versions.json +++ b/versions.json @@ -4,7 +4,7 @@ "version": "3.12.36" }, "v4": { - "version": "4.0.0-beta.93" + "version": "4.0.0-beta.94" } } } From e4aed185a28a283278bab60b30ab7ecf0457887c Mon Sep 17 00:00:00 2001 From: Andras Bacsai Date: Wed, 18 Oct 2023 12:48:29 +0200 Subject: [PATCH 07/22] fix: label generation --- app/Models/Service.php | 2 +- bootstrap/helpers/docker.php | 10 ++++++---- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/app/Models/Service.php b/app/Models/Service.php index 95fe826fb..9d14e18eb 100644 --- a/app/Models/Service.php +++ b/app/Models/Service.php @@ -538,7 +538,7 @@ class Service extends BaseModel $serviceLabels = $serviceLabels->merge($defaultLabels); if (!$isDatabase && $fqdns->count() > 0) { if ($fqdns) { - $serviceLabels = $serviceLabels->merge(fqdnLabelsForTraefik($this->uuid, $fqdns, true)); + $serviceLabels = $serviceLabels->merge(fqdnLabelsForTraefik($fqdns, true)); } } data_set($service, 'labels', $serviceLabels->toArray()); diff --git a/bootstrap/helpers/docker.php b/bootstrap/helpers/docker.php index dfa4c1788..4fc87ac13 100644 --- a/bootstrap/helpers/docker.php +++ b/bootstrap/helpers/docker.php @@ -147,11 +147,12 @@ function defaultLabels($id, $name, $pull_request_id = 0, string $type = 'applica } return $labels; } -function fqdnLabelsForTraefik($uuid, Collection $domains, bool $is_force_https_enabled, $onlyPort = null) +function fqdnLabelsForTraefik(Collection $domains, bool $is_force_https_enabled, $onlyPort = null) { $labels = collect([]); $labels->push('traefik.enable=true'); foreach ($domains as $domain) { + $uuid = (string)new Cuid2(7); $url = Url::fromString($domain); $host = $url->getHost(); $path = $url->getPath(); @@ -212,13 +213,13 @@ function generateLabelsApplication(Application $application, ?ApplicationPreview $onlyPort = $ports[0]; } $pull_request_id = data_get($preview, 'pull_request_id', 0); - // $container_name = generateApplicationContainerName($application, $pull_request_id); + $container_name = generateApplicationContainerName($application, $pull_request_id); $appId = $application->id; if ($pull_request_id !== 0 && $pull_request_id !== null) { $appId = $appId . '-pr-' . $pull_request_id; } $labels = collect([]); - $labels = $labels->merge(defaultLabels($appId, $application->uuid, $pull_request_id)); + $labels = $labels->merge(defaultLabels($appId, $container_name, $pull_request_id)); if ($application->fqdn) { if ($pull_request_id !== 0) { $domains = Str::of(data_get($preview, 'fqdn'))->explode(','); @@ -226,7 +227,8 @@ function generateLabelsApplication(Application $application, ?ApplicationPreview $domains = Str::of(data_get($application, 'fqdn'))->explode(','); } // Add Traefik labels no matter which proxy is selected - $labels = $labels->merge(fqdnLabelsForTraefik($application->uuid, $domains, $application->settings->is_force_https_enabled, $onlyPort)); + $labels = $labels->merge(fqdnLabelsForTraefik($domains, $application->settings->is_force_https_enabled, $onlyPort)); } + ray($labels); return $labels->all(); } From eedc3faba38c278a13efe213bc62d69d1db4cd6a Mon Sep 17 00:00:00 2001 From: Andras Bacsai Date: Wed, 18 Oct 2023 14:14:40 +0200 Subject: [PATCH 08/22] fix: labels --- .../Livewire/Project/Application/General.php | 4 ++++ app/Models/Service.php | 2 +- bootstrap/helpers/docker.php | 16 +++++++--------- config/sentry.php | 2 +- config/version.php | 2 +- versions.json | 2 +- 6 files changed, 15 insertions(+), 13 deletions(-) diff --git a/app/Http/Livewire/Project/Application/General.php b/app/Http/Livewire/Project/Application/General.php index c99650912..b4ebfff5d 100644 --- a/app/Http/Livewire/Project/Application/General.php +++ b/app/Http/Livewire/Project/Application/General.php @@ -119,6 +119,7 @@ class General extends Component public function instantSave() { // @TODO: find another way - if possible + $force_https = $this->application->settings->is_force_https_enabled; $this->application->settings->is_static = $this->is_static; if ($this->is_static) { $this->application->ports_exposes = 80; @@ -137,6 +138,9 @@ class General extends Component $this->emit('success', 'Application settings updated!'); $this->checkLabelUpdates(); $this->isConfigurationChanged = $this->application->isConfigurationChanged(); + if ($force_https !== $this->is_force_https_enabled) { + $this->resetDefaultLabels(false); + } } public function getWildcardDomain() diff --git a/app/Models/Service.php b/app/Models/Service.php index 9d14e18eb..95fe826fb 100644 --- a/app/Models/Service.php +++ b/app/Models/Service.php @@ -538,7 +538,7 @@ class Service extends BaseModel $serviceLabels = $serviceLabels->merge($defaultLabels); if (!$isDatabase && $fqdns->count() > 0) { if ($fqdns) { - $serviceLabels = $serviceLabels->merge(fqdnLabelsForTraefik($fqdns, true)); + $serviceLabels = $serviceLabels->merge(fqdnLabelsForTraefik($this->uuid, $fqdns, true)); } } data_set($service, 'labels', $serviceLabels->toArray()); diff --git a/bootstrap/helpers/docker.php b/bootstrap/helpers/docker.php index 4fc87ac13..179abecb9 100644 --- a/bootstrap/helpers/docker.php +++ b/bootstrap/helpers/docker.php @@ -147,12 +147,11 @@ function defaultLabels($id, $name, $pull_request_id = 0, string $type = 'applica } return $labels; } -function fqdnLabelsForTraefik(Collection $domains, bool $is_force_https_enabled, $onlyPort = null) +function fqdnLabelsForTraefik(string $uuid, Collection $domains, bool $is_force_https_enabled, $onlyPort = null) { $labels = collect([]); $labels->push('traefik.enable=true'); - foreach ($domains as $domain) { - $uuid = (string)new Cuid2(7); + foreach ($domains as $loop => $domain) { $url = Url::fromString($domain); $host = $url->getHost(); $path = $url->getPath(); @@ -161,8 +160,8 @@ function fqdnLabelsForTraefik(Collection $domains, bool $is_force_https_enabled, if (is_null($port) && !is_null($onlyPort)) { $port = $onlyPort; } - $http_label = "{$uuid}-http"; - $https_label = "{$uuid}-https"; + $http_label = "{$uuid}-{$loop}-http"; + $https_label = "{$uuid}-{$loop}-https"; if ($schema === 'https') { // Set labels for https @@ -213,13 +212,13 @@ function generateLabelsApplication(Application $application, ?ApplicationPreview $onlyPort = $ports[0]; } $pull_request_id = data_get($preview, 'pull_request_id', 0); - $container_name = generateApplicationContainerName($application, $pull_request_id); + // $container_name = generateApplicationContainerName($application, $pull_request_id); $appId = $application->id; if ($pull_request_id !== 0 && $pull_request_id !== null) { $appId = $appId . '-pr-' . $pull_request_id; } $labels = collect([]); - $labels = $labels->merge(defaultLabels($appId, $container_name, $pull_request_id)); + $labels = $labels->merge(defaultLabels($appId, $application->uuid, $pull_request_id)); if ($application->fqdn) { if ($pull_request_id !== 0) { $domains = Str::of(data_get($preview, 'fqdn'))->explode(','); @@ -227,8 +226,7 @@ function generateLabelsApplication(Application $application, ?ApplicationPreview $domains = Str::of(data_get($application, 'fqdn'))->explode(','); } // Add Traefik labels no matter which proxy is selected - $labels = $labels->merge(fqdnLabelsForTraefik($domains, $application->settings->is_force_https_enabled, $onlyPort)); + $labels = $labels->merge(fqdnLabelsForTraefik($application->uuid, $domains, $application->settings->is_force_https_enabled, $onlyPort)); } - ray($labels); return $labels->all(); } diff --git a/config/sentry.php b/config/sentry.php index 61c18786f..c6c30f70a 100644 --- a/config/sentry.php +++ b/config/sentry.php @@ -7,7 +7,7 @@ return [ // The release version of your application // Example with dynamic git hash: trim(exec('git --git-dir ' . base_path('.git') . ' log --pretty="%h" -n1 HEAD')) - 'release' => '4.0.0-beta.94', + 'release' => '4.0.0-beta.95', // When left empty or `null` the Laravel environment will be used 'environment' => config('app.env'), diff --git a/config/version.php b/config/version.php index 4daf3b070..b5427b80b 100644 --- a/config/version.php +++ b/config/version.php @@ -1,3 +1,3 @@ Date: Wed, 18 Oct 2023 14:22:09 +0200 Subject: [PATCH 09/22] fix: email channel no recepients --- app/Notifications/Channels/EmailChannel.php | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/app/Notifications/Channels/EmailChannel.php b/app/Notifications/Channels/EmailChannel.php index 5cd4ceaeb..cd6dc4b56 100644 --- a/app/Notifications/Channels/EmailChannel.php +++ b/app/Notifications/Channels/EmailChannel.php @@ -30,7 +30,12 @@ class EmailChannel ); } catch (Exception $e) { ray($e->getMessage()); - send_internal_notification("EmailChannel error: {$e->getMessage()}. Failed to send email to: " . implode(', ', $recepients) . " with subject: {$mailMessage->subject}"); + $message = "EmailChannel error: {$e->getMessage()}. Failed to send email to:"; + if (isset($recepients)) { + $message .= implode(', ', $recepients); + } + $message .= " with subject: {$mailMessage->subject}"; + send_internal_notification($message); throw $e; } } From 4f588ced96b99af48f88de57f739917db3464572 Mon Sep 17 00:00:00 2001 From: Andras Bacsai Date: Wed, 18 Oct 2023 14:43:48 +0200 Subject: [PATCH 10/22] call handle not matter what --- app/Jobs/ContainerStatusJob.php | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/app/Jobs/ContainerStatusJob.php b/app/Jobs/ContainerStatusJob.php index 1c8cf1919..9b5f9dc48 100644 --- a/app/Jobs/ContainerStatusJob.php +++ b/app/Jobs/ContainerStatusJob.php @@ -19,6 +19,7 @@ use Illuminate\Queue\InteractsWithQueue; use Illuminate\Queue\Middleware\WithoutOverlapping; use Illuminate\Queue\SerializesModels; use Illuminate\Support\Arr; +use Illuminate\Support\Facades\Log; use Illuminate\Support\Str; class ContainerStatusJob implements ShouldQueue, ShouldBeEncrypted @@ -40,9 +41,7 @@ class ContainerStatusJob implements ShouldQueue, ShouldBeEncrypted public function __construct(public Server $server) { - if (isDev()) { - $this->handle(); - } + $this->handle(); } public function handle() @@ -76,6 +75,7 @@ class ContainerStatusJob implements ShouldQueue, ShouldBeEncrypted $this->server->update([ 'unreachable_count' => 0, ]); + Log::info("Server {$this->server->id} is reachable."); } else { $serverUptimeCheckNumber++; $this->server->settings()->update([ @@ -129,7 +129,6 @@ class ContainerStatusJob implements ShouldQueue, ShouldBeEncrypted } catch (\Throwable $e) { ray($e); } - } else { $this->server->proxy->status = data_get($foundProxyContainer, 'State.Status'); $this->server->save(); From 3a27d13c3eaa9cc7831fde74a458776e4ae4e332 Mon Sep 17 00:00:00 2001 From: Andras Bacsai Date: Wed, 18 Oct 2023 14:46:26 +0200 Subject: [PATCH 11/22] fix --- app/Jobs/ContainerStatusJob.php | 2 -- 1 file changed, 2 deletions(-) diff --git a/app/Jobs/ContainerStatusJob.php b/app/Jobs/ContainerStatusJob.php index 9b5f9dc48..4e9f53990 100644 --- a/app/Jobs/ContainerStatusJob.php +++ b/app/Jobs/ContainerStatusJob.php @@ -19,7 +19,6 @@ use Illuminate\Queue\InteractsWithQueue; use Illuminate\Queue\Middleware\WithoutOverlapping; use Illuminate\Queue\SerializesModels; use Illuminate\Support\Arr; -use Illuminate\Support\Facades\Log; use Illuminate\Support\Str; class ContainerStatusJob implements ShouldQueue, ShouldBeEncrypted @@ -75,7 +74,6 @@ class ContainerStatusJob implements ShouldQueue, ShouldBeEncrypted $this->server->update([ 'unreachable_count' => 0, ]); - Log::info("Server {$this->server->id} is reachable."); } else { $serverUptimeCheckNumber++; $this->server->settings()->update([ From 76aab722b8222a58ee04d2a4316352656e0c3e50 Mon Sep 17 00:00:00 2001 From: Andras Bacsai Date: Wed, 18 Oct 2023 15:07:04 +0200 Subject: [PATCH 12/22] fix: limit horizon processes to 2 by default --- config/horizon.php | 8 ++++---- config/sentry.php | 2 +- config/version.php | 2 +- versions.json | 2 +- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/config/horizon.php b/config/horizon.php index f35cbd731..14d20e1cf 100644 --- a/config/horizon.php +++ b/config/horizon.php @@ -210,13 +210,13 @@ return [ 'production' => [ 's6' => [ 'autoScalingStrategy' => 'size', - 'maxProcesses' => env('HORIZON_MAX_PROCESSES', 10), + 'maxProcesses' => env('HORIZON_MAX_PROCESSES', 2), 'balanceMaxShift' => env('HORIZON_BALANCE_MAX_SHIFT', 1), 'balanceCooldown' => env('HORIZON_BALANCE_COOLDOWN', 1), ], 'long-running' => [ 'autoScalingStrategy' => 'size', - 'maxProcesses' => env('HORIZON_MAX_PROCESSES', 10), + 'maxProcesses' => env('HORIZON_MAX_PROCESSES', 2), 'balanceMaxShift' => env('HORIZON_BALANCE_MAX_SHIFT', 1), 'balanceCooldown' => env('HORIZON_BALANCE_COOLDOWN', 1), ], @@ -225,13 +225,13 @@ return [ 'local' => [ 's6' => [ 'autoScalingStrategy' => 'size', - 'maxProcesses' => env('HORIZON_MAX_PROCESSES', 10), + 'maxProcesses' => env('HORIZON_MAX_PROCESSES', 2), 'balanceMaxShift' => env('HORIZON_BALANCE_MAX_SHIFT', 1), 'balanceCooldown' => env('HORIZON_BALANCE_COOLDOWN', 1), ], 'long-running' => [ 'autoScalingStrategy' => 'size', - 'maxProcesses' => env('HORIZON_MAX_PROCESSES', 10), + 'maxProcesses' => env('HORIZON_MAX_PROCESSES', 2), 'balanceMaxShift' => env('HORIZON_BALANCE_MAX_SHIFT', 1), 'balanceCooldown' => env('HORIZON_BALANCE_COOLDOWN', 1), ], diff --git a/config/sentry.php b/config/sentry.php index c6c30f70a..106c80041 100644 --- a/config/sentry.php +++ b/config/sentry.php @@ -7,7 +7,7 @@ return [ // The release version of your application // Example with dynamic git hash: trim(exec('git --git-dir ' . base_path('.git') . ' log --pretty="%h" -n1 HEAD')) - 'release' => '4.0.0-beta.95', + 'release' => '4.0.0-beta.96', // When left empty or `null` the Laravel environment will be used 'environment' => config('app.env'), diff --git a/config/version.php b/config/version.php index b5427b80b..ffa1baf40 100644 --- a/config/version.php +++ b/config/version.php @@ -1,3 +1,3 @@ Date: Wed, 18 Oct 2023 15:23:43 +0200 Subject: [PATCH 13/22] fix: add custom port as ssh option to deploy_key based commands --- app/Jobs/ApplicationDeploymentJob.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/Jobs/ApplicationDeploymentJob.php b/app/Jobs/ApplicationDeploymentJob.php index a6d6050bf..258651035 100644 --- a/app/Jobs/ApplicationDeploymentJob.php +++ b/app/Jobs/ApplicationDeploymentJob.php @@ -555,7 +555,7 @@ class ApplicationDeploymentJob implements ShouldQueue, ShouldBeEncrypted $port = $matches[0]; } $private_key = base64_encode($this->application->private_key->private_key); - $git_clone_command = "GIT_SSH_COMMAND=\"ssh -p $port -o LogLevel=ERROR -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -i /root/.ssh/id_rsa\" {$git_clone_command} {$this->application->git_repository} {$this->basedir}"; + $git_clone_command = "GIT_SSH_COMMAND=\"ssh -o ConnectTimeout=30 -p $port -o Port=$port -o LogLevel=ERROR -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -i /root/.ssh/id_rsa\" {$git_clone_command} {$this->application->git_repository} {$this->basedir}"; $git_clone_command = $this->set_git_import_settings($git_clone_command); $commands = collect([ executeInDocker($this->deployment_uuid, "mkdir -p /root/.ssh"), From 2ad7c2b1ce3a61b7bc69a6b6acfaf6ae9453cce6 Mon Sep 17 00:00:00 2001 From: Andras Bacsai Date: Wed, 18 Oct 2023 15:33:07 +0200 Subject: [PATCH 14/22] fix: remove custom port from git repo url --- app/Jobs/ApplicationDeploymentJob.php | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/app/Jobs/ApplicationDeploymentJob.php b/app/Jobs/ApplicationDeploymentJob.php index 258651035..3091bc339 100644 --- a/app/Jobs/ApplicationDeploymentJob.php +++ b/app/Jobs/ApplicationDeploymentJob.php @@ -75,6 +75,8 @@ class ApplicationDeploymentJob implements ShouldQueue, ShouldBeEncrypted private string $serverUserHomeDir = '/root'; private string $dockerConfigFileExists = 'NOK'; + private int $customPort = 22; + public $tries = 1; public function __construct(int $application_deployment_queue_id) { @@ -167,6 +169,15 @@ class ApplicationDeploymentJob implements ShouldQueue, ShouldBeEncrypted // Get user home directory $this->serverUserHomeDir = instant_remote_process(["echo \$HOME"], $this->server); $this->dockerConfigFileExists = instant_remote_process(["test -f {$this->serverUserHomeDir}/.docker/config.json && echo 'OK' || echo 'NOK'"], $this->server); + + // Check custom port + preg_match('/(?<=:)\d+(?=\/)/', $this->application->git_repository, $matches); + if (count($matches) === 1) { + $this->customPort = $matches[0]; + $gitHost = str($this->application->git_repository)->before(':'); + $gitRepo = str($this->application->git_repository)->after('/'); + $this->application->git_repository = "$gitHost:$gitRepo"; + } try { if ($this->application->dockerfile) { $this->deploy_simple_dockerfile(); @@ -549,13 +560,8 @@ class ApplicationDeploymentJob implements ShouldQueue, ShouldBeEncrypted } } if ($this->application->deploymentType() === 'deploy_key') { - $port = 22; - preg_match('/(?<=:)\d+(?=\/)/', $this->application->git_repository, $matches); - if (count($matches) === 1) { - $port = $matches[0]; - } $private_key = base64_encode($this->application->private_key->private_key); - $git_clone_command = "GIT_SSH_COMMAND=\"ssh -o ConnectTimeout=30 -p $port -o Port=$port -o LogLevel=ERROR -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -i /root/.ssh/id_rsa\" {$git_clone_command} {$this->application->git_repository} {$this->basedir}"; + $git_clone_command = "GIT_SSH_COMMAND=\"ssh -o ConnectTimeout=30 -p {$this->customPort} -o Port={$this->customPort} -o LogLevel=ERROR -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -i /root/.ssh/id_rsa\" {$git_clone_command} {$this->application->git_repository} {$this->basedir}"; $git_clone_command = $this->set_git_import_settings($git_clone_command); $commands = collect([ executeInDocker($this->deployment_uuid, "mkdir -p /root/.ssh"), From 2f93f4450fb2a9025a9a9e3892d0195d82cbf0e5 Mon Sep 17 00:00:00 2001 From: Andras Bacsai Date: Wed, 18 Oct 2023 15:43:14 +0200 Subject: [PATCH 15/22] fix: containerStatus job --- app/Console/Kernel.php | 9 ++------- app/Jobs/ContainerStatusJob.php | 30 ++++++++++++------------------ 2 files changed, 14 insertions(+), 25 deletions(-) diff --git a/app/Console/Kernel.php b/app/Console/Kernel.php index 730cf4113..8bbab0081 100644 --- a/app/Console/Kernel.php +++ b/app/Console/Kernel.php @@ -19,13 +19,9 @@ class Kernel extends ConsoleKernel protected function schedule(Schedule $schedule): void { if (isDev()) { - // $schedule->job(new ContainerStatusJob(Server::find(0)))->everyTenMinutes()->onOneServer(); - // $schedule->command('horizon:snapshot')->everyMinute(); + $schedule->command('horizon:snapshot')->everyMinute(); $schedule->job(new CleanupInstanceStuffsJob)->everyMinute()->onOneServer(); - // $schedule->job(new CheckResaleLicenseJob)->hourly(); - // $schedule->job(new DockerCleanupJob)->everyOddHour(); - // $this->instance_auto_update($schedule); - // $this->check_scheduled_backups($schedule); + $this->check_scheduled_backups($schedule); $this->check_resources($schedule); $this->cleanup_servers($schedule); $this->check_scheduled_backups($schedule); @@ -69,7 +65,6 @@ class Kernel extends ConsoleKernel } private function check_scheduled_backups($schedule) { - ray('check_scheduled_backups'); $scheduled_backups = ScheduledDatabaseBackup::all(); if ($scheduled_backups->isEmpty()) { ray('no scheduled backups'); diff --git a/app/Jobs/ContainerStatusJob.php b/app/Jobs/ContainerStatusJob.php index 4e9f53990..24c869219 100644 --- a/app/Jobs/ContainerStatusJob.php +++ b/app/Jobs/ContainerStatusJob.php @@ -12,7 +12,6 @@ use App\Notifications\Server\Revived; use App\Notifications\Server\Unreachable; use Illuminate\Bus\Queueable; use Illuminate\Contracts\Queue\ShouldBeEncrypted; -use Illuminate\Contracts\Queue\ShouldBeUnique; use Illuminate\Contracts\Queue\ShouldQueue; use Illuminate\Foundation\Bus\Dispatchable; use Illuminate\Queue\InteractsWithQueue; @@ -25,28 +24,23 @@ class ContainerStatusJob implements ShouldQueue, ShouldBeEncrypted { use Dispatchable, InteractsWithQueue, Queueable, SerializesModels; - public $tries = 1; - public $timeout = 120; - - public function middleware(): array - { - return [(new WithoutOverlapping($this->server->uuid))->dontRelease()]; - } - - public function uniqueId(): string - { - return $this->server->uuid; - } - public function __construct(public Server $server) { - $this->handle(); + } + public function middleware(): array + { + return [(new WithoutOverlapping($this->server->id))->dontRelease()]; } - public function handle() + public function uniqueId(): int { + return $this->server->id; + } + + public function handle(): void + { + ray("checking server status for {$this->server->id}"); try { - // ray("checking server status for {$this->server->id}"); // ray()->clearAll(); $serverUptimeCheckNumber = $this->server->unreachable_count; $serverUptimeCheckNumberMax = 3; @@ -305,7 +299,7 @@ class ContainerStatusJob implements ShouldQueue, ShouldBeEncrypted } catch (\Throwable $e) { send_internal_notification('ContainerStatusJob failed with: ' . $e->getMessage()); ray($e->getMessage()); - return handleError($e); + handleError($e); } } } From 5b8785d1a91e7163e99ab41b1fb60923cd6b8f58 Mon Sep 17 00:00:00 2001 From: Andras Bacsai Date: Wed, 18 Oct 2023 15:49:50 +0200 Subject: [PATCH 16/22] update prod compose --- config/sentry.php | 2 +- config/version.php | 2 +- docker-compose.prod.yml | 1 + 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/config/sentry.php b/config/sentry.php index 106c80041..1c75b9d50 100644 --- a/config/sentry.php +++ b/config/sentry.php @@ -7,7 +7,7 @@ return [ // The release version of your application // Example with dynamic git hash: trim(exec('git --git-dir ' . base_path('.git') . ' log --pretty="%h" -n1 HEAD')) - 'release' => '4.0.0-beta.96', + 'release' => '4.0.0-beta.97', // When left empty or `null` the Laravel environment will be used 'environment' => config('app.env'), diff --git a/config/version.php b/config/version.php index ffa1baf40..af0296c72 100644 --- a/config/version.php +++ b/config/version.php @@ -1,3 +1,3 @@ Date: Wed, 18 Oct 2023 15:49:58 +0200 Subject: [PATCH 17/22] version++ --- versions.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/versions.json b/versions.json index 627803969..f006c3fdb 100644 --- a/versions.json +++ b/versions.json @@ -4,7 +4,7 @@ "version": "3.12.36" }, "v4": { - "version": "4.0.0-beta.96" + "version": "4.0.0-beta.97" } } } From 2c40e93d3b3dedb5f2f3eae4ec8c1df3d0be53f0 Mon Sep 17 00:00:00 2001 From: Andras Bacsai Date: Wed, 18 Oct 2023 18:02:09 +0200 Subject: [PATCH 18/22] wip: PAT by team --- app/Http/Livewire/Dashboard.php | 4 ++++ app/Models/PersonalAccessToken.php | 15 +++++++++++++ app/Models/User.php | 22 ++++++++++++++++++++ app/Providers/AppServiceProvider.php | 4 ++++ resources/views/livewire/dashboard.blade.php | 6 ++++-- 5 files changed, 49 insertions(+), 2 deletions(-) create mode 100644 app/Models/PersonalAccessToken.php diff --git a/app/Http/Livewire/Dashboard.php b/app/Http/Livewire/Dashboard.php index 723b00f7f..b46df481a 100644 --- a/app/Http/Livewire/Dashboard.php +++ b/app/Http/Livewire/Dashboard.php @@ -17,6 +17,10 @@ class Dashboard extends Component $this->servers = Server::ownedByCurrentTeam()->get(); $this->projects = Project::ownedByCurrentTeam()->get(); } + // public function createToken() { + // $token = auth()->user()->createToken('test'); + // ray($token); + // } // public function getIptables() // { // $servers = Server::ownedByCurrentTeam()->get(); diff --git a/app/Models/PersonalAccessToken.php b/app/Models/PersonalAccessToken.php new file mode 100644 index 000000000..f5b11883a --- /dev/null +++ b/app/Models/PersonalAccessToken.php @@ -0,0 +1,15 @@ +teams()->attach($new_team, ['role' => 'owner']); }); } + public function createToken(string $name, array $abilities = ['*'], DateTimeInterface $expiresAt = null) + { + ray('asd'); + $plainTextToken = sprintf( + '%s%s%s', + config('sanctum.token_prefix', ''), + $tokenEntropy = Str::random(40), + hash('crc32b', $tokenEntropy) + ); + $token = $this->tokens()->create([ + 'name' => $name, + 'token' => hash('sha256', $plainTextToken), + 'abilities' => $abilities, + 'expires_at' => $expiresAt, + 'team_id' => session('currentTeam')->id + ]); + + return new NewAccessToken($token, $token->getKey().'|'.$plainTextToken); + } public function teams() { return $this->belongsToMany(Team::class)->withPivot('role'); diff --git a/app/Providers/AppServiceProvider.php b/app/Providers/AppServiceProvider.php index 07d02cd03..c50a53bef 100644 --- a/app/Providers/AppServiceProvider.php +++ b/app/Providers/AppServiceProvider.php @@ -4,6 +4,8 @@ namespace App\Providers; use Illuminate\Support\Facades\Http; use Illuminate\Support\ServiceProvider; +use Laravel\Sanctum\Sanctum; +use App\Models\PersonalAccessToken; class AppServiceProvider extends ServiceProvider { @@ -13,6 +15,8 @@ class AppServiceProvider extends ServiceProvider public function boot(): void { + Sanctum::usePersonalAccessTokenModel(PersonalAccessToken::class); + Http::macro('github', function (string $api_url, string|null $github_access_token = null) { if ($github_access_token) { return Http::withHeaders([ diff --git a/resources/views/livewire/dashboard.blade.php b/resources/views/livewire/dashboard.blade.php index e6a7cf975..7ceb40d7a 100644 --- a/resources/views/livewire/dashboard.blade.php +++ b/resources/views/livewire/dashboard.blade.php @@ -62,7 +62,7 @@ @endforeach
@if ($projects->count() > 0) -

Servers

+

Servers

@endif @if ($servers->count() === 1)
@@ -97,7 +97,9 @@ @endforeach
- + {{--

Tokens

+ {{auth()->user()->tokens}} + Create Token --}}