do not use hash routing for tabs

add empty project creation
if local image is found, we only refresh the configuration
This commit is contained in:
Andras Bacsai
2023-04-26 14:29:33 +02:00
parent 9f32730714
commit 2c68eed072
13 changed files with 138 additions and 109 deletions

View File

@@ -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,
],
];

View File

@@ -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') {

View File

@@ -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;

View File

@@ -0,0 +1,19 @@
<?php
namespace App\Http\Livewire\Project\New;
use App\Models\Project;
use Livewire\Component;
class EmptyProject extends Component
{
public function createEmptyProject()
{
$project = Project::create([
'name' => fake()->company(),
'description' => fake()->sentence(),
'team_id' => session('currentTeam')->id,
]);
return redirect()->route('project.environments', ['project_uuid' => $project->uuid, 'environment_name' => 'production']);
}
}

View File

@@ -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? 😢'",

View File

@@ -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();