From 22178df8ae6420ef926a866ce415df12d3771ab3 Mon Sep 17 00:00:00 2001 From: Stuart Rowlands Date: Wed, 6 Dec 2023 15:42:14 -0800 Subject: [PATCH] Add support for command execution in containers. --- .../Livewire/Project/Application/Command.php | 105 ++++++++++++++++++ .../components/applications/navbar.blade.php | 4 + .../components/databases/navbar.blade.php | 4 + .../project/application/command.blade.php | 30 +++++ .../livewire/project/service/show.blade.php | 4 + routes/web.php | 4 + 6 files changed, 151 insertions(+) create mode 100644 app/Http/Livewire/Project/Application/Command.php create mode 100644 resources/views/livewire/project/application/command.blade.php diff --git a/app/Http/Livewire/Project/Application/Command.php b/app/Http/Livewire/Project/Application/Command.php new file mode 100644 index 000000000..3ee89dbdf --- /dev/null +++ b/app/Http/Livewire/Project/Application/Command.php @@ -0,0 +1,105 @@ + 'required', + 'container' => 'required', + 'command' => 'required', + ]; + protected $validationAttributes = [ + 'server' => 'server', + 'container' => 'container', + 'command' => 'command', + ]; + + public function mount() + { + + $this->containers = collect(); + $this->parameters = get_route_parameters(); + $this->query = request()->query(); + if (data_get($this->parameters, 'application_uuid')) { + $this->type = 'application'; + $this->resource = Application::where('uuid', $this->parameters['application_uuid'])->firstOrFail(); + $this->status = $this->resource->status; + $this->server = $this->resource->destination->server; + $containers = getCurrentApplicationContainerStatus($this->server, $this->resource->id, 0); + if ($containers->count() > 0) { + $containers->each(function ($container) { + $this->containers->push(str_replace('/', '', $container['Names'])); + }); + } + } else if (data_get($this->parameters, 'database_uuid')) { + $this->type = 'database'; + $resource = StandalonePostgresql::where('uuid', $this->parameters['database_uuid'])->first(); + if (is_null($resource)) { + $resource = StandaloneRedis::where('uuid', $this->parameters['database_uuid'])->first(); + if (is_null($resource)) { + $resource = StandaloneMongodb::where('uuid', $this->parameters['database_uuid'])->first(); + if (is_null($resource)) { + $resource = StandaloneMysql::where('uuid', $this->parameters['database_uuid'])->first(); + if (is_null($resource)) { + $resource = StandaloneMariadb::where('uuid', $this->parameters['database_uuid'])->first(); + if (is_null($resource)) { + abort(404); + } + } + } + } + } + $this->resource = $resource; + $this->status = $this->resource->status; + $this->server = $this->resource->destination->server; + $this->container = $this->resource->uuid; + $this->containers->push($this->container); + } else if (data_get($this->parameters, 'service_uuid')) { + $this->type = 'service'; + $this->resource = Service::where('uuid', $this->parameters['service_uuid'])->firstOrFail(); + $service_name = data_get($this->parameters, 'service_name'); + $this->serviceSubType = $this->resource->applications()->where('name', $service_name)->first(); + if (!$this->serviceSubType) { + $this->serviceSubType = $this->resource->databases()->where('name', $service_name)->first(); + } + $this->status = $this->resource->status; + $this->server = $this->resource->server; + $this->container = data_get($this->parameters, 'service_name') . '-' . $this->resource->uuid; + $this->containers->push($this->container); + } + } + + public function runCommand() + { + $this->validate(); + try { + if (!empty($this->dir)) { + $exec = "docker exec -w {$this->dir} {$this->container} {$this->command}"; + } + else { + $exec = "docker exec {$this->container} {$this->command}"; + } + $activity = remote_process([$exec], $this->server, ignore_errors: true); + $this->emit('newMonitorActivity', $activity->id); + } catch (\Throwable $e) { + return handleError($e, $this); + } + } +} \ No newline at end of file diff --git a/resources/views/components/applications/navbar.blade.php b/resources/views/components/applications/navbar.blade.php index 9bd048e26..c77f04eb2 100644 --- a/resources/views/components/applications/navbar.blade.php +++ b/resources/views/components/applications/navbar.blade.php @@ -11,6 +11,10 @@ href="{{ route('project.application.logs', $parameters) }}"> + + +
@if ($application->build_pack === 'dockercompose' && is_null($application->docker_compose_raw)) diff --git a/resources/views/components/databases/navbar.blade.php b/resources/views/components/databases/navbar.blade.php index ecf4ca573..b8ca54c0c 100644 --- a/resources/views/components/databases/navbar.blade.php +++ b/resources/views/components/databases/navbar.blade.php @@ -7,6 +7,10 @@ href="{{ route('project.database.logs', $parameters) }}"> + + + @if ( $database->getMorphClass() === 'App\Models\StandalonePostgresql' || $database->getMorphClass() === 'App\Models\StandaloneMongodb' || diff --git a/resources/views/livewire/project/application/command.blade.php b/resources/views/livewire/project/application/command.blade.php new file mode 100644 index 000000000..dcade27dc --- /dev/null +++ b/resources/views/livewire/project/application/command.blade.php @@ -0,0 +1,30 @@ +
+ @if ($type === 'application') + + @elseif ($type === 'database') + + @elseif ($type === 'service') + + + @endif +
+ + + + + @foreach ($containers as $container) + + @endforeach + + Execute Command + + +
+ +
+
\ No newline at end of file diff --git a/resources/views/livewire/project/service/show.blade.php b/resources/views/livewire/project/service/show.blade.php index f556d6df8..dbffe0352 100644 --- a/resources/views/livewire/project/service/show.blade.php +++ b/resources/views/livewire/project/service/show.blade.php @@ -26,6 +26,10 @@ @endif + + +
@isset($serviceApplication) diff --git a/routes/web.php b/routes/web.php index 1e276e738..a527d732c 100644 --- a/routes/web.php +++ b/routes/web.php @@ -6,6 +6,7 @@ use App\Http\Controllers\MagicController; use App\Http\Controllers\ProjectController; use App\Http\Livewire\Project\Application\Configuration as ApplicationConfiguration; +use App\Http\Livewire\Project\Application\Command as ApplicationCommand; use App\Http\Livewire\Boarding\Index as BoardingIndex; use App\Http\Livewire\Project\Service\Index as ServiceIndex; use App\Http\Livewire\Project\Service\Show as ServiceShow; @@ -111,18 +112,21 @@ )->name('project.application.deployment'); Route::get('/project/{project_uuid}/{environment_name}/application/{application_uuid}/logs', Logs::class)->name('project.application.logs'); + Route::get('/project/{project_uuid}/{environment_name}/application/{application_uuid}/command', ApplicationCommand::class)->name('project.application.command'); // Databases Route::get('/project/{project_uuid}/{environment_name}/database/{database_uuid}', [DatabaseController::class, 'configuration'])->name('project.database.configuration'); Route::get('/project/{project_uuid}/{environment_name}/database/{database_uuid}/backups', [DatabaseController::class, 'backups'])->name('project.database.backups.all'); Route::get('/project/{project_uuid}/{environment_name}/database/{database_uuid}/backups/{backup_uuid}', [DatabaseController::class, 'executions'])->name('project.database.backups.executions'); Route::get('/project/{project_uuid}/{environment_name}/database/{database_uuid}/logs', Logs::class)->name('project.database.logs'); + Route::get('/project/{project_uuid}/{environment_name}/database/{database_uuid}/command', ApplicationCommand::class)->name('project.database.command'); // Services Route::get('/project/{project_uuid}/{environment_name}/service/{service_uuid}', ServiceIndex::class)->name('project.service.configuration'); Route::get('/project/{project_uuid}/{environment_name}/service/{service_uuid}/{service_name}', ServiceShow::class)->name('project.service.show'); Route::get('/project/{project_uuid}/{environment_name}/service/{service_uuid}/{service_name}/logs', Logs::class)->name('project.service.logs'); + Route::get('/project/{project_uuid}/{environment_name}/service/{service_uuid}/{service_name}/command', ApplicationCommand::class)->name('project.service.command'); }); Route::middleware(['auth'])->group(function () {