mirror of
https://github.com/vitodeploy/vito.git
synced 2025-07-01 14:06:15 +00:00
Compare commits
4 Commits
Author | SHA1 | Date | |
---|---|---|---|
f06b8f7d20 | |||
f120a570e8 | |||
2d7f225ff2 | |||
31bd146239 |
27
.github/ISSUE_TEMPLATE/bug_report.md
vendored
Normal file
27
.github/ISSUE_TEMPLATE/bug_report.md
vendored
Normal 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.
|
12
.github/ISSUE_TEMPLATE/feature_request.md
vendored
Normal file
12
.github/ISSUE_TEMPLATE/feature_request.md
vendored
Normal 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/
|
@ -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);
|
||||||
|
@ -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;
|
||||||
|
|
||||||
|
41
app/Http/Livewire/Sites/UpdateVHost.php
Normal file
41
app/Http/Livewire/Sites/UpdateVHost.php
Normal 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');
|
||||||
|
}
|
||||||
|
}
|
@ -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),
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
26
app/SSHCommands/Nginx/GetNginxVHostCommand.php
Executable file
26
app/SSHCommands/Nginx/GetNginxVHostCommand.php
Executable 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();
|
||||||
|
}
|
||||||
|
}
|
@ -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'),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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')
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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', [
|
||||||
|
@ -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
|
||||||
*/
|
*/
|
||||||
|
@ -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'] ?? '',
|
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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
|
||||||
|
@ -30,6 +30,7 @@
|
|||||||
|
|
||||||
'disks' => [
|
'disks' => [
|
||||||
|
|
||||||
|
// should be FilesystemAdapter
|
||||||
'local' => [
|
'local' => [
|
||||||
'driver' => 'local',
|
'driver' => 'local',
|
||||||
'root' => storage_path('app'),
|
'root' => storage_path('app'),
|
||||||
|
1
resources/commands/webserver/nginx/get-vhost.sh
Executable file
1
resources/commands/webserver/nginx/get-vhost.sh
Executable file
@ -0,0 +1 @@
|
|||||||
|
cat /etc/nginx/sites-available/__domain__
|
34
resources/views/livewire/sites/update-v-host.blade.php
Normal file
34
resources/views/livewire/sites/update-v-host.blade.php
Normal 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>
|
@ -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>
|
||||||
|
@ -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);
|
||||||
|
Reference in New Issue
Block a user