From 2c68eed072dbf8580a903f8f1aaf28a0fb8d1f9d Mon Sep 17 00:00:00 2001 From: Andras Bacsai Date: Wed, 26 Apr 2023 14:29:33 +0200 Subject: [PATCH] do not use hash routing for tabs add empty project creation if local image is found, we only refresh the configuration --- app/Http/Kernel.php | 2 +- .../Livewire/Project/Application/Deploy.php | 8 +- .../Livewire/Project/Application/General.php | 3 - .../Livewire/Project/New/EmptyProject.php | 19 ++++ app/Jobs/DeployApplicationJob.php | 88 +++++++++++-------- app/Models/Application.php | 68 +++++++------- ...1717_create_application_settings_table.php | 1 - resources/views/components/layout.blade.php | 2 +- .../project/application/deploy.blade.php | 5 +- .../project/application/general.blade.php | 3 +- .../project/new/empty-project.blade.php | 1 + .../application/configuration.blade.php | 27 +++--- resources/views/project/new.blade.php | 20 ++--- 13 files changed, 138 insertions(+), 109 deletions(-) create mode 100644 app/Http/Livewire/Project/New/EmptyProject.php create mode 100644 resources/views/livewire/project/new/empty-project.blade.php diff --git a/app/Http/Kernel.php b/app/Http/Kernel.php index c34cdcf11..f25f52c39 100644 --- a/app/Http/Kernel.php +++ b/app/Http/Kernel.php @@ -40,7 +40,7 @@ class Kernel extends HttpKernel 'api' => [ // \Laravel\Sanctum\Http\Middleware\EnsureFrontendRequestsAreStateful::class, - \Illuminate\Routing\Middleware\ThrottleRequests::class.':api', + \Illuminate\Routing\Middleware\ThrottleRequests::class . ':api', \Illuminate\Routing\Middleware\SubstituteBindings::class, ], ]; diff --git a/app/Http/Livewire/Project/Application/Deploy.php b/app/Http/Livewire/Project/Application/Deploy.php index 830018c6b..a4ac4ab2d 100644 --- a/app/Http/Livewire/Project/Application/Deploy.php +++ b/app/Http/Livewire/Project/Application/Deploy.php @@ -64,7 +64,7 @@ class Deploy extends Component public function delete() { - $this->kill(); + $this->stop(); Application::find($this->applicationId)->delete(); return redirect()->route('project.resources', [ 'project_uuid' => $this->parameters['project_uuid'], @@ -72,12 +72,6 @@ class Deploy extends Component ]); } public function stop() - { - runRemoteCommandSync($this->destination->server, ["docker stop -t 0 {$this->application->uuid} >/dev/null 2>&1"]); - $this->application->status = 'stopped'; - $this->application->save(); - } - public function kill() { runRemoteCommandSync($this->destination->server, ["docker rm -f {$this->application->uuid}"]); if ($this->application->status != 'exited') { diff --git a/app/Http/Livewire/Project/Application/General.php b/app/Http/Livewire/Project/Application/General.php index 2d903862e..6e7941b72 100644 --- a/app/Http/Livewire/Project/Application/General.php +++ b/app/Http/Livewire/Project/Application/General.php @@ -22,7 +22,6 @@ class General extends Component public bool $is_git_lfs_allowed; public bool $is_debug; public bool $is_previews; - public bool $is_bot; public bool $is_custom_ssl; public bool $is_http2; public bool $is_auto_deploy; @@ -49,7 +48,6 @@ class General extends Component $this->application->settings->is_git_lfs_allowed = $this->is_git_lfs_allowed; $this->application->settings->is_debug = $this->is_debug; $this->application->settings->is_previews = $this->is_previews; - $this->application->settings->is_bot = $this->is_bot; $this->application->settings->is_custom_ssl = $this->is_custom_ssl; $this->application->settings->is_http2 = $this->is_http2; $this->application->settings->is_auto_deploy = $this->is_auto_deploy; @@ -65,7 +63,6 @@ class General extends Component $this->is_git_lfs_allowed = $this->application->settings->is_git_lfs_allowed; $this->is_debug = $this->application->settings->is_debug; $this->is_previews = $this->application->settings->is_previews; - $this->is_bot = $this->application->settings->is_bot; $this->is_custom_ssl = $this->application->settings->is_custom_ssl; $this->is_http2 = $this->application->settings->is_http2; $this->is_auto_deploy = $this->application->settings->is_auto_deploy; diff --git a/app/Http/Livewire/Project/New/EmptyProject.php b/app/Http/Livewire/Project/New/EmptyProject.php new file mode 100644 index 000000000..5dc99490e --- /dev/null +++ b/app/Http/Livewire/Project/New/EmptyProject.php @@ -0,0 +1,19 @@ + fake()->company(), + 'description' => fake()->sentence(), + 'team_id' => session('currentTeam')->id, + ]); + return redirect()->route('project.environments', ['project_uuid' => $project->uuid, 'environment_name' => 'production']); + } +} diff --git a/app/Jobs/DeployApplicationJob.php b/app/Jobs/DeployApplicationJob.php index fa40f0e36..e1780de84 100644 --- a/app/Jobs/DeployApplicationJob.php +++ b/app/Jobs/DeployApplicationJob.php @@ -35,6 +35,7 @@ class DeployApplicationJob implements ShouldQueue protected Activity $activity; protected string $git_commit; protected string $workdir; + protected string $docker_compose; public static int $batch_counter = 0; /** @@ -70,7 +71,33 @@ class DeployApplicationJob implements ShouldQueue ->event(ActivityTypes::DEPLOYMENT->value) ->log("[]"); } + protected function stopRunningContainer() + { + $this->executeNow([ + "echo -n 'Removing old instance... '", + $this->execute_in_builder("docker rm -f {$this->application->uuid} >/dev/null 2>&1"), + "echo 'Done.'", + "echo -n 'Starting your application... '", + ]); + } + protected function startByComposeFile() + { + $this->executeNow([ + $this->execute_in_builder("docker compose --project-directory {$this->workdir} up -d >/dev/null"), + ], isDebuggable: true); + $this->executeNow([ + "echo 'Done. 🎉'", + ], isFinished: true); + } + protected function generateComposeFile() + { + $this->docker_compose = $this->generate_docker_compose(); + $docker_compose_base64 = base64_encode($this->docker_compose); + $this->executeNow([ + $this->execute_in_builder("echo '{$docker_compose_base64}' | base64 -d > {$this->workdir}/docker-compose.yml") + ], hideFromOutput: true); + } /** * Execute the job. */ @@ -86,7 +113,7 @@ class DeployApplicationJob implements ShouldQueue $wildcard_domain = $project_wildcard_domain ?? $global_wildcard_domain ?? null; // Set wildcard domain - if (!$this->application->settings->is_bot && !$this->application->fqdn && $wildcard_domain) { + if (!$this->application->fqdn && $wildcard_domain) { $this->application->fqdn = 'http://' . $this->application->uuid . '.' . $wildcard_domain; $this->application->save(); } @@ -119,35 +146,30 @@ class DeployApplicationJob implements ShouldQueue if (!$this->force_rebuild) { $this->executeNow([ - "docker inspect {$this->application->uuid} --format '{{json .Config.Image}}' 2>&1", - ], 'stopped_container_image', hideFromOutput: true, ignoreErrors: true); - $image = $this->activity->properties->get('stopped_container_image'); - if (isset($image)) { - $image = explode(':', str_replace('"', '', $image))[1]; - if ($image == $this->git_commit) { - $this->executeNow([ - "echo -n 'Application found locally with the same Git Commit SHA. Starting it... '" - ]); - $this->executeNow([ - "docker start {$this->application->uuid}" - ], hideFromOutput: true); + "docker images -q {$this->application->uuid}:{$this->git_commit} 2>/dev/null", + ], 'local_image_found', hideFromOutput: true, ignoreErrors: true); + $image_found = Str::of($this->activity->properties->get('local_image_found'))->trim()->isNotEmpty(); + if ($image_found) { + $this->executeNow([ + "echo 'Docker Image found locally with the same Git Commit SHA. Build skipped...'" + ]); + // Generate docker-compose.yml + $this->generateComposeFile(); - $this->executeNow([ - "echo 'Done. 🎉'", - ], isFinished: true); - return; - } + // Stop running container + $this->stopRunningContainer(); + + // Start application + $this->startByComposeFile(); + return; } } $this->executeNow([ $this->execute_in_builder("rm -fr {$this->workdir}/.git") ], hideFromOutput: true); - $docker_compose = $this->generate_docker_compose(); - $docker_compose_base64 = base64_encode($docker_compose); - $this->executeNow([ - $this->execute_in_builder("echo '{$docker_compose_base64}' | base64 -d > {$this->workdir}/docker-compose.yml") - ], hideFromOutput: true); + // Generate docker-compose.yml + $this->generateComposeFile(); $this->executeNow([ "echo -n 'Generating nixpacks configuration... '", @@ -183,24 +205,18 @@ COPY --from={$this->application->uuid}:{$this->git_commit}-build /app/{$this->ap $this->execute_in_builder("docker build -f {$this->workdir}/Dockerfile --build-arg SOURCE_COMMIT={$this->git_commit} --progress plain -t {$this->application->uuid}:{$this->git_commit} {$this->workdir}"), ], isDebuggable: true); } + $this->executeNow([ "echo 'Done.'", - "echo -n 'Removing old instance... '", - $this->execute_in_builder("docker rm -f {$this->application->uuid} >/dev/null 2>&1"), - "echo 'Done.'", - "echo -n 'Starting your application... '", ]); - $this->executeNow([ - $this->execute_in_builder("docker compose --project-directory {$this->workdir} up -d >/dev/null"), - ], isDebuggable: true); + // Stop running container + $this->stopRunningContainer(); + + // Start application + $this->startByComposeFile(); - $this->executeNow([ - "echo 'Done. 🎉'", - ], isFinished: true); // Saving docker-compose.yml - Storage::disk('deployments')->put(Str::kebab($this->application->name) . '/docker-compose.yml', $docker_compose); - // } - + Storage::disk('deployments')->put(Str::kebab($this->application->name) . '/docker-compose.yml', $this->docker_compose); } catch (\Exception $e) { $this->executeNow([ "echo 'Oops something is not okay, are you okay? 😢'", diff --git a/app/Models/Application.php b/app/Models/Application.php index 05d185aac..48234efe0 100644 --- a/app/Models/Application.php +++ b/app/Models/Application.php @@ -36,6 +36,43 @@ class Application extends BaseModel 'publish_directory', ]; + public function publishDirectory(): Attribute + { + return Attribute::make( + set: fn ($value) => $value ? '/' . ltrim($value, '/') : null, + ); + } + public function baseDirectory(): Attribute + { + return Attribute::make( + set: fn ($value) => '/' . ltrim($value, '/'), + ); + } + public function portsMappings(): Attribute + { + return Attribute::make( + set: fn ($value) => $value === "" ? null : $value, + ); + } + public function portsMappingsArray(): Attribute + { + return Attribute::make( + get: fn () => + is_null($this->ports_mappings) + ? [] + : explode(',', $this->ports_mappings), + + ); + } + public function portsExposesArray(): Attribute + { + return Attribute::make( + get: fn () => + is_null($this->ports_exposes) + ? [] + : explode(',', $this->ports_exposes) + ); + } public function environment() { return $this->belongsTo(Environment::class); @@ -57,38 +94,7 @@ class Application extends BaseModel return $this->morphMany(LocalPersistentVolume::class, 'resource'); } - public function publishDirectory(): Attribute - { - return Attribute::make( - set: fn ($value) => $value ? '/' . ltrim($value, '/') : null, - ); - } - public function baseDirectory(): Attribute - { - return Attribute::make( - set: fn ($value) => '/' . ltrim($value, '/'), - ); - } - public function portsMappingsArray(): Attribute - { - return Attribute::make( - get: fn () => - is_null($this->ports_mappings) - ? [] - : explode(',', $this->ports_mappings) - ); - } - public function portsExposesArray(): Attribute - { - return Attribute::make( - get: fn () => - is_null($this->ports_exposes) - ? [] - : explode(',', $this->ports_exposes) - - ); - } public function deployments() { return Activity::where('subject_id', $this->id)->where('properties->deployment_uuid', '!=', null)->orderBy('created_at', 'desc')->get(); diff --git a/database/migrations/2023_03_27_081717_create_application_settings_table.php b/database/migrations/2023_03_27_081717_create_application_settings_table.php index ccb89926e..91a83ad57 100644 --- a/database/migrations/2023_03_27_081717_create_application_settings_table.php +++ b/database/migrations/2023_03_27_081717_create_application_settings_table.php @@ -20,7 +20,6 @@ return new class extends Migration $table->boolean('is_dual_cert')->default(false); $table->boolean('is_debug')->default(false); $table->boolean('is_previews')->default(false); - $table->boolean('is_bot')->default(false); $table->boolean('is_custom_ssl')->default(false); $table->boolean('is_http2')->default(false); $table->foreignId('application_id'); diff --git a/resources/views/components/layout.blade.php b/resources/views/components/layout.blade.php index a16775485..0cbfd94b7 100644 --- a/resources/views/components/layout.blade.php +++ b/resources/views/components/layout.blade.php @@ -15,7 +15,7 @@ @livewireStyles - +
{{ $slot }} diff --git a/resources/views/livewire/project/application/deploy.blade.php b/resources/views/livewire/project/application/deploy.blade.php index c278f615c..06e71bf55 100644 --- a/resources/views/livewire/project/application/deploy.blade.php +++ b/resources/views/livewire/project/application/deploy.blade.php @@ -5,15 +5,14 @@ @if ($application->status === 'running') - @else @endif - + @if ($application->status === 'running') - @if (!data_get($application, 'settings.is_bot') && data_get($application, 'fqdn')) + @if (data_get($application, 'fqdn')) Open URL @endif diff --git a/resources/views/livewire/project/application/general.blade.php b/resources/views/livewire/project/application/general.blade.php index 0aee12182..4e3cf0bdd 100644 --- a/resources/views/livewire/project/application/general.blade.php +++ b/resources/views/livewire/project/application/general.blade.php @@ -28,7 +28,7 @@ @if ($application->settings->is_static) @else - + @endif @@ -43,7 +43,6 @@ - diff --git a/resources/views/livewire/project/new/empty-project.blade.php b/resources/views/livewire/project/new/empty-project.blade.php new file mode 100644 index 000000000..160b19b5b --- /dev/null +++ b/resources/views/livewire/project/new/empty-project.blade.php @@ -0,0 +1 @@ + diff --git a/resources/views/project/application/configuration.blade.php b/resources/views/project/application/configuration.blade.php index 5b6877a32..4b2f8ce6b 100644 --- a/resources/views/project/application/configuration.blade.php +++ b/resources/views/project/application/configuration.blade.php @@ -1,29 +1,34 @@

Configuration

-
+
-
+
-
+
-
+
-
+
-
+
diff --git a/resources/views/project/new.blade.php b/resources/views/project/new.blade.php index 48c0335ed..b39e6bf04 100644 --- a/resources/views/project/new.blade.php +++ b/resources/views/project/new.blade.php @@ -4,28 +4,22 @@ @elseif ($type === 'resource')

New Resource

@endif -
+
- - + + @if ($type === 'project') - + @endif
-
+
-
+
github-private-repo
-
- empty-project -
-
+
Choose any option