Compare commits

...

4 Commits
0.6.0 ... 0.7.0

Author SHA1 Message Date
f06b8f7d20 update vhost and bug fix (#87) 2024-01-05 22:07:45 +01:00
f120a570e8 Update issue templates 2024-01-05 20:38:48 +01:00
2d7f225ff2 define storage instances with phpdoc 2024-01-03 22:31:50 +01:00
31bd146239 small typo fix 2024-01-02 20:18:25 +01:00
19 changed files with 207 additions and 17 deletions

27
.github/ISSUE_TEMPLATE/bug_report.md vendored Normal file
View File

@ -0,0 +1,27 @@
---
name: Bug report
about: Create a report to help us improve
title: ''
labels: bug
assignees: ''
---
**Describe the bug**
A clear and concise description of what the bug is.
**To Reproduce**
Steps to reproduce the behavior:
1. Go to '...'
2. Click on '....'
3. Scroll down to '....'
4. See error
**Expected behavior**
A clear and concise description of what you expected to happen.
**Screenshots**
If applicable, add screenshots to help explain your problem.
**Additional context**
Add any other context about the problem here.

View File

@ -0,0 +1,12 @@
---
name: Feature request
about: Suggest an idea for this project
title: ''
labels: feature
assignees: ''
---
To request a feature or suggest an idea please add it to the feedback boards
https://features.vitodeploy.com/

View File

@ -17,9 +17,12 @@ public function update(Service $service, string $ini): void
{ {
$tmpName = Str::random(10).strtotime('now'); $tmpName = Str::random(10).strtotime('now');
try { try {
Storage::disk('local')->put($tmpName, $ini); /** @var \Illuminate\Filesystem\FilesystemAdapter $storageDisk */
$storageDisk = Storage::disk('local');
$storageDisk->put($tmpName, $ini);
$service->server->ssh('root')->upload( $service->server->ssh('root')->upload(
Storage::disk('local')->path($tmpName), $storageDisk->path($tmpName),
"/etc/php/$service->version/cli/php.ini" "/etc/php/$service->version/cli/php.ini"
); );
$this->deleteTempFile($tmpName); $this->deleteTempFile($tmpName);

View File

@ -9,7 +9,9 @@ interface Webserver
{ {
public function createVHost(Site $site): void; public function createVHost(Site $site): void;
public function updateVHost(Site $site): void; public function updateVHost(Site $site, bool $noSSL = false, ?string $vhost = null): void;
public function getVHost(Site $site): string;
public function deleteSite(Site $site): void; public function deleteSite(Site $site): void;

View File

@ -0,0 +1,41 @@
<?php
namespace App\Http\Livewire\Sites;
use App\Models\Site;
use App\Traits\HasToast;
use App\Traits\RefreshComponentOnBroadcast;
use Illuminate\Contracts\View\View;
use Livewire\Component;
use Throwable;
class UpdateVHost extends Component
{
use HasToast;
use RefreshComponentOnBroadcast;
public Site $site;
public string $vHost = 'Loading...';
public function loadVHost(): void
{
$this->vHost = $this->site->server->webserver()->handler()->getVHost($this->site);
}
public function update(): void
{
try {
$this->site->server->webserver()->handler()->updateVHost($this->site, false, $this->vHost);
$this->toast()->success('VHost updated successfully!');
} catch (Throwable $e) {
$this->toast()->error($e->getMessage());
}
}
public function render(): View
{
return view('livewire.sites.update-v-host');
}
}

View File

@ -343,10 +343,13 @@ public function sshKey(): array
]; ];
} }
/** @var \Illuminate\Filesystem\FilesystemAdapter $storageDisk */
$storageDisk = Storage::disk(config('core.key_pairs_disk'));
return [ return [
'public_key' => Str::replace("\n", '', Storage::disk(config('core.key_pairs_disk'))->get($this->id.'.pub')), 'public_key' => Str::replace("\n", '', Storage::disk(config('core.key_pairs_disk'))->get($this->id.'.pub')),
'public_key_path' => Storage::disk(config('core.key_pairs_disk'))->path($this->id.'.pub'), 'public_key_path' => $storageDisk->path($this->id.'.pub'),
'private_key_path' => Storage::disk(config('core.key_pairs_disk'))->path((string) $this->id), 'private_key_path' => $storageDisk->path((string) $this->id),
]; ];
} }

View File

@ -0,0 +1,26 @@
<?php
namespace App\SSHCommands\Nginx;
use App\SSHCommands\Command;
use Illuminate\Support\Facades\File;
class GetNginxVHostCommand extends Command
{
public function __construct(
protected string $domain
) {
}
public function file(): string
{
return File::get(resource_path('commands/webserver/nginx/get-vhost.sh'));
}
public function content(): string
{
return str($this->file())
->replace('__domain__', $this->domain)
->toString();
}
}

View File

@ -164,10 +164,12 @@ private function createKeyPair(): void
$result = $this->ec2Client->createKeyPair([ $result = $this->ec2Client->createKeyPair([
'KeyName' => $keyName, 'KeyName' => $keyName,
]); ]);
Storage::disk(config('core.key_pairs_disk'))->put((string) $this->server->id, $result['KeyMaterial']); /** @var \Illuminate\Filesystem\FilesystemAdapter $storageDisk */
$storageDisk = Storage::disk(config('core.key_pairs_disk'));
$storageDisk->put((string) $this->server->id, $result['KeyMaterial']);
generate_public_key( generate_public_key(
Storage::disk(config('core.key_pairs_disk'))->path((string) $this->server->id), $storageDisk->path((string) $this->server->id),
Storage::disk(config('core.key_pairs_disk'))->path($this->server->id.'.pub'), $storageDisk->path($this->server->id.'.pub'),
); );
} }

View File

@ -17,6 +17,8 @@ public function __construct(?Server $server = null)
protected function generateKeyPair(): void protected function generateKeyPair(): void
{ {
generate_key_pair(Storage::disk(config('core.key_pairs_disk'))->path((string) $this->server->id)); /** @var \Illuminate\Filesystem\FilesystemAdapter $storageDisk */
$storageDisk = Storage::disk(config('core.key_pairs_disk'));
generate_key_pair($storageDisk->path((string) $this->server->id));
} }
} }

View File

@ -59,13 +59,15 @@ public function regions(): array
public function create(): void public function create(): void
{ {
/** @var \Illuminate\Filesystem\FilesystemAdapter $storageDisk */
$storageDisk = Storage::disk(config('core.key_pairs_disk'));
File::copy( File::copy(
storage_path(config('core.ssh_private_key_name')), storage_path(config('core.ssh_private_key_name')),
Storage::disk(config('core.key_pairs_disk'))->path($this->server->id) $storageDisk->path($this->server->id)
); );
File::copy( File::copy(
storage_path(config('core.ssh_public_key_name')), storage_path(config('core.ssh_public_key_name')),
Storage::disk(config('core.key_pairs_disk'))->path($this->server->id.'.pub') $storageDisk->path($this->server->id.'.pub')
); );
} }

View File

@ -85,7 +85,9 @@ public function regions(): array
public function create(): void public function create(): void
{ {
// generate key pair // generate key pair
generate_key_pair(Storage::disk(config('core.key_pairs_disk'))->path((string) $this->server->id)); /** @var \Illuminate\Filesystem\FilesystemAdapter $storageDisk */
$storageDisk = Storage::disk(config('core.key_pairs_disk'));
generate_key_pair($storageDisk->path((string) $this->server->id));
$createSshKey = Http::withToken($this->server->serverProvider->credentials['token']) $createSshKey = Http::withToken($this->server->serverProvider->credentials['token'])
->post($this->apiUrl.'/ssh-keys', [ ->post($this->apiUrl.'/ssh-keys', [

View File

@ -9,6 +9,7 @@
use App\SSHCommands\Nginx\ChangeNginxPHPVersionCommand; use App\SSHCommands\Nginx\ChangeNginxPHPVersionCommand;
use App\SSHCommands\Nginx\CreateNginxVHostCommand; use App\SSHCommands\Nginx\CreateNginxVHostCommand;
use App\SSHCommands\Nginx\DeleteNginxSiteCommand; use App\SSHCommands\Nginx\DeleteNginxSiteCommand;
use App\SSHCommands\Nginx\GetNginxVHostCommand;
use App\SSHCommands\Nginx\UpdateNginxRedirectsCommand; use App\SSHCommands\Nginx\UpdateNginxRedirectsCommand;
use App\SSHCommands\Nginx\UpdateNginxVHostCommand; use App\SSHCommands\Nginx\UpdateNginxVHostCommand;
use App\SSHCommands\SSL\CreateCustomSSLCommand; use App\SSHCommands\SSL\CreateCustomSSLCommand;
@ -39,19 +40,30 @@ public function createVHost(Site $site): void
/** /**
* @throws Throwable * @throws Throwable
*/ */
public function updateVHost(Site $site, bool $noSSL = false): void public function updateVHost(Site $site, bool $noSSL = false, ?string $vhost = null): void
{ {
$this->service->server->ssh()->exec( $this->service->server->ssh()->exec(
new UpdateNginxVHostCommand( new UpdateNginxVHostCommand(
$site->domain, $site->domain,
$site->path, $site->path,
$this->generateVhost($site, $noSSL) $vhost ?? $this->generateVhost($site, $noSSL)
), ),
'update-vhost', 'update-vhost',
$site->id $site->id
); );
} }
public function getVHost(Site $site): string
{
return $this->service->server->ssh()->exec(
new GetNginxVHostCommand(
$site->domain
),
'get-vhost',
$site->id
);
}
/** /**
* @throws Throwable * @throws Throwable
*/ */

View File

@ -55,6 +55,7 @@ public function createFields(array $input): array
'source_control_id' => $input['source_control'] ?? '', 'source_control_id' => $input['source_control'] ?? '',
'repository' => $input['repository'] ?? '', 'repository' => $input['repository'] ?? '',
'branch' => $input['branch'] ?? '', 'branch' => $input['branch'] ?? '',
'php_version' => $input['php_version'] ?? '',
]; ];
} }
@ -62,7 +63,6 @@ public function data(array $input): array
{ {
return [ return [
'composer' => isset($input['composer']) && $input['composer'], 'composer' => isset($input['composer']) && $input['composer'],
'php_version' => $input['php_version'] ?? '',
]; ];
} }

View File

@ -39,8 +39,8 @@
'ssh_user' => env('SSH_USER', 'vito'), 'ssh_user' => env('SSH_USER', 'vito'),
'ssh_public_key_name' => env('SSH_PUBLIC_KEY_NAME', 'ssh-public.key'), 'ssh_public_key_name' => env('SSH_PUBLIC_KEY_NAME', 'ssh-public.key'),
'ssh_private_key_name' => env('SSH_PRIVATE_KEY_NAME', 'ssh-private.pem'), 'ssh_private_key_name' => env('SSH_PRIVATE_KEY_NAME', 'ssh-private.pem'),
'logs_disk' => env('SERVER_LOGS_DISK', 'server-logs-local'), 'logs_disk' => env('SERVER_LOGS_DISK', 'server-logs-local'), // should to be FilesystemAdapter storage
'key_pairs_disk' => env('KEY_PAIRS_DISK', 'key-pairs-local'), 'key_pairs_disk' => env('KEY_PAIRS_DISK', 'key-pairs-local'), // should to be FilesystemAdapter storage
/* /*
* General * General

View File

@ -30,6 +30,7 @@
'disks' => [ 'disks' => [
// should be FilesystemAdapter
'local' => [ 'local' => [
'driver' => 'local', 'driver' => 'local',
'root' => storage_path('app'), 'root' => storage_path('app'),

View File

@ -0,0 +1 @@
cat /etc/nginx/sites-available/__domain__

View File

@ -0,0 +1,34 @@
<x-card>
<x-slot name="title">{{ __('Update VHost') }}</x-slot>
<x-slot name="description">{{ __("You can change your site's PHP version here") }}</x-slot>
<form
id="update-vhost"
wire:submit.prevent="update"
class="space-y-6"
>
<div>
<x-textarea
id="vHost"
wire:init="loadVHost"
wire:model.defer="vHost"
rows="10"
class="mt-1 block w-full"
></x-textarea>
@error('vHost')
<x-input-error
class="mt-2"
:messages="$message"
/>
@enderror
</div>
</form>
<x-slot name="actions">
<x-primary-button
form="update-vhost"
wire:loading.attr="disabled"
>{{ __('Save') }}</x-primary-button>
</x-slot>
</x-card>

View File

@ -5,6 +5,8 @@
<livewire:sites.update-source-control-provider :site="$site"/> <livewire:sites.update-source-control-provider :site="$site"/>
<livewire:sites.update-v-host :site="$site"/>
<x-card> <x-card>
<x-slot name="title">{{ __("Delete Site") }}</x-slot> <x-slot name="title">{{ __("Delete Site") }}</x-slot>
<x-slot name="description">{{ __("Permanently delete the site from server") }}</x-slot> <x-slot name="description">{{ __("Permanently delete the site from server") }}</x-slot>

View File

@ -5,11 +5,13 @@
use App\Enums\SiteStatus; use App\Enums\SiteStatus;
use App\Enums\SiteType; use App\Enums\SiteType;
use App\Enums\SourceControl; use App\Enums\SourceControl;
use App\Facades\SSH;
use App\Http\Livewire\Sites\ChangePhpVersion; use App\Http\Livewire\Sites\ChangePhpVersion;
use App\Http\Livewire\Sites\CreateSite; use App\Http\Livewire\Sites\CreateSite;
use App\Http\Livewire\Sites\DeleteSite; use App\Http\Livewire\Sites\DeleteSite;
use App\Http\Livewire\Sites\SitesList; use App\Http\Livewire\Sites\SitesList;
use App\Http\Livewire\Sites\UpdateSourceControlProvider; use App\Http\Livewire\Sites\UpdateSourceControlProvider;
use App\Http\Livewire\Sites\UpdateVHost;
use App\Jobs\Site\CreateVHost; use App\Jobs\Site\CreateVHost;
use App\Models\Site; use App\Models\Site;
use Illuminate\Foundation\Testing\RefreshDatabase; use Illuminate\Foundation\Testing\RefreshDatabase;
@ -107,6 +109,22 @@ public function test_change_php_version(): void
Bus::assertDispatched(\App\Jobs\Site\ChangePHPVersion::class); Bus::assertDispatched(\App\Jobs\Site\ChangePHPVersion::class);
} }
public function test_update_v_host(): void
{
SSH::fake();
$this->actingAs($this->user);
$site = Site::factory()->create([
'server_id' => $this->server->id,
]);
Livewire::test(UpdateVHost::class, ['site' => $site])
->set('vHost', 'test-vhost')
->call('update')
->assertSuccessful();
}
public function test_update_source_control(): void public function test_update_source_control(): void
{ {
$this->actingAs($this->user); $this->actingAs($this->user);