This commit is contained in:
Saeed Vaziry
2023-07-02 12:47:50 +02:00
commit 5c72f12490
825 changed files with 41659 additions and 0 deletions

View File

@ -0,0 +1,38 @@
<?php
namespace App\SiteTypes;
use App\Contracts\SiteType;
use App\Events\Broadcast;
use App\Jobs\Site\DeleteSite;
use App\Models\Site;
use Closure;
abstract class AbstractSiteType implements SiteType
{
protected Site $site;
public function __construct(Site $site)
{
$this->site = $site;
}
public function delete(): void
{
dispatch(new DeleteSite($this->site))->onConnection('ssh');
}
protected function progress(int $percentage): Closure
{
return function () use ($percentage) {
$this->site->progress = $percentage;
$this->site->save();
event(
new Broadcast('site-installation-progress', [
'site' => $this->site,
'percentage' => $percentage,
])
);
};
}
}

7
app/SiteTypes/Laravel.php Executable file
View File

@ -0,0 +1,7 @@
<?php
namespace App\SiteTypes;
class Laravel extends PHPSite
{
}

117
app/SiteTypes/PHPSite.php Executable file
View File

@ -0,0 +1,117 @@
<?php
namespace App\SiteTypes;
use App\Enums\SiteStatus;
use App\Events\Broadcast;
use App\Jobs\Site\CloneRepository;
use App\Jobs\Site\ComposerInstall;
use App\Jobs\Site\CreateVHost;
use Illuminate\Support\Facades\Bus;
use Illuminate\Support\Facades\Log;
use Illuminate\Validation\Rule;
use Throwable;
class PHPSite extends AbstractSiteType
{
public function language(): string
{
return 'php';
}
public function createValidationRules(array $input): array
{
return [
'php_version' => [
'required',
'in:'.implode(',', $this->site->server->installedPHPVersions()),
],
'source_control' => [
'required',
Rule::exists('source_controls', 'provider'),
],
'repository' => [
'required',
],
'branch' => [
'required',
],
];
}
public function createFields(array $input): array
{
return [
'web_directory' => $input['web_directory'] ?? '',
'source_control' => $input['source_control'] ?? '',
'repository' => $input['repository'] ?? '',
'branch' => $input['branch'] ?? '',
];
}
public function data(array $input): array
{
return [
'composer' => (bool) $input['composer'],
];
}
public function install(): void
{
$chain = [
new CreateVHost($this->site),
$this->progress(30),
new CloneRepository($this->site),
$this->progress(65),
function () {
$this->site->php()?->restart();
},
];
if ($this->site->type_data['composer']) {
$chain[] = new ComposerInstall($this->site);
}
$chain[] = function () {
$this->site->update([
'status' => SiteStatus::READY,
'progress' => 100,
]);
event(
new Broadcast('install-site-finished', [
'site' => $this->site,
])
);
/** @todo notify */
};
Bus::chain($chain)
->catch(function (Throwable $e) {
$this->site->update([
'status' => SiteStatus::INSTALLATION_FAILED,
]);
event(
new Broadcast('install-site-failed', [
'site' => $this->site,
])
);
/** @todo notify */
Log::error('install-site-error', [
'error' => (string) $e,
]);
throw $e;
})
->onConnection('ssh-long')
->dispatch();
}
public function editValidationRules(array $input): array
{
return [];
}
public function edit(): void
{
//
}
}

172
app/SiteTypes/Wordpress.php Executable file
View File

@ -0,0 +1,172 @@
<?php
namespace App\SiteTypes;
use App\Enums\SiteStatus;
use App\Events\Broadcast;
use App\Jobs\Site\CreateVHost;
use App\Jobs\Site\InstallWordpress;
use App\SSHCommands\UpdateWordpressCommand;
use Illuminate\Support\Facades\Bus;
use Illuminate\Support\Facades\Log;
use Throwable;
class Wordpress extends AbstractSiteType
{
public function language(): string
{
return 'php';
}
public function createValidationRules(array $input): array
{
return [
'title' => 'required',
'username' => 'required',
'password' => 'required',
'email' => 'required|email',
'database' => 'required',
'database_user' => 'required',
];
}
public function createFields(array $input): array
{
return [
'web_directory' => $input['web_directory'] ?? '',
];
}
public function data(array $input): array
{
$data = $this->site->type_data;
$data['url'] = $this->site->url;
if (isset($input['title']) && $input['title']) {
$data['title'] = $input['title'];
}
if (isset($input['username']) && $input['username']) {
$data['username'] = $input['username'];
}
if (isset($input['email']) && $input['email']) {
$data['email'] = $input['email'];
}
if (isset($input['password']) && $input['password']) {
$data['password'] = $input['password'];
}
if (isset($input['database']) && $input['database']) {
$data['database'] = $input['database'];
}
if (isset($input['database_user']) && $input['database_user']) {
$data['database_user'] = $input['database_user'];
}
if (isset($input['url']) && $input['url']) {
$data['url'] = $input['url'];
}
return $data;
}
public function install(): void
{
$chain = [
new CreateVHost($this->site),
$this->progress(30),
new InstallWordpress($this->site),
$this->progress(65),
function () {
$this->site->php()?->restart();
},
];
$chain[] = function () {
$this->site->update([
'status' => SiteStatus::READY,
'progress' => 100,
]);
event(
new Broadcast('install-site-finished', [
'site' => $this->site,
])
);
/** @todo notify */
};
Bus::chain($chain)
->catch(function (Throwable $e) {
$this->site->update([
'status' => SiteStatus::INSTALLATION_FAILED,
]);
event(
new Broadcast('install-site-failed', [
'site' => $this->site,
])
);
/** @todo notify */
Log::error('install-site-error', [
'error' => (string) $e,
]);
throw $e;
})
->onConnection('ssh-long')
->dispatch();
}
public function editValidationRules(array $input): array
{
return [
'title' => 'required',
'url' => 'required',
// 'email' => 'required|email',
];
}
public function edit(): void
{
$this->site->status = 'installing';
$this->site->progress = 90;
$this->site->save();
$chain = [
function () {
$this->site->server->ssh()->exec(
new UpdateWordpressCommand(
$this->site->path,
$this->site->type_data['url'],
$this->site->type_data['username'] ?? '',
$this->site->type_data['password'] ?? '',
$this->site->type_data['email'] ?? '',
$this->site->type_data['title'] ?? '',
),
'update-wordpress',
$this->site->id
);
$this->site->update([
'status' => SiteStatus::READY,
]);
event(
new Broadcast('install-site-finished', [
'site' => $this->site,
])
);
},
];
Bus::chain($chain)
->catch(function (Throwable $e) {
$this->site->update([
'status' => SiteStatus::INSTALLATION_FAILED,
]);
event(
new Broadcast('install-site-failed', [
'site' => $this->site,
])
);
/** @todo notify */
Log::error('install-site-error', [
'error' => (string) $e,
]);
throw $e;
})
->onConnection('ssh')
->dispatch();
}
}