mirror of
https://github.com/vitodeploy/vito.git
synced 2025-07-07 17:02:34 +00:00
Plugins base (#613)
* wip * wip * cleanup * notification channels * phpstan * services * remove server types * refactoring * refactoring
This commit is contained in:
@ -29,7 +29,7 @@ public function create(Server $server, array $input): Database
|
||||
/** @var Service $service */
|
||||
$service = $server->database();
|
||||
|
||||
/** @var \App\SSH\Services\Database\Database $databaseHandler */
|
||||
/** @var \App\Services\Database\Database $databaseHandler */
|
||||
$databaseHandler = $service->handler();
|
||||
$databaseHandler->create($database->name, $database->charset, $database->collation);
|
||||
$database->status = DatabaseStatus::READY;
|
||||
|
@ -6,7 +6,7 @@
|
||||
use App\Models\DatabaseUser;
|
||||
use App\Models\Server;
|
||||
use App\Models\Service;
|
||||
use App\SSH\Services\Database\Database;
|
||||
use App\Services\Database\Database;
|
||||
use Illuminate\Support\Facades\Validator;
|
||||
use Illuminate\Validation\Rule;
|
||||
use Illuminate\Validation\ValidationException;
|
||||
|
@ -13,7 +13,7 @@ public function delete(Server $server, Database $database): void
|
||||
{
|
||||
/** @var Service $service */
|
||||
$service = $server->database();
|
||||
/** @var \App\SSH\Services\Database\Database $handler */
|
||||
/** @var \App\Services\Database\Database $handler */
|
||||
$handler = $service->handler();
|
||||
$handler->delete($database->name);
|
||||
$database->delete();
|
||||
|
@ -5,7 +5,7 @@
|
||||
use App\Models\DatabaseUser;
|
||||
use App\Models\Server;
|
||||
use App\Models\Service;
|
||||
use App\SSH\Services\Database\Database;
|
||||
use App\Services\Database\Database;
|
||||
|
||||
class DeleteDatabaseUser
|
||||
{
|
||||
|
@ -39,7 +39,7 @@ public function link(DatabaseUser $databaseUser, array $input): DatabaseUser
|
||||
/** @var Service $service */
|
||||
$service = $databaseUser->server->database();
|
||||
|
||||
/** @var \App\SSH\Services\Database\Database $handler */
|
||||
/** @var \App\Services\Database\Database $handler */
|
||||
$handler = $service->handler();
|
||||
|
||||
// Unlink the user from all databases
|
||||
|
@ -28,7 +28,7 @@ public function restore(BackupFile $backupFile, array $input): void
|
||||
dispatch(function () use ($backupFile, $database): void {
|
||||
/** @var Service $service */
|
||||
$service = $database->server->database();
|
||||
/** @var \App\SSH\Services\Database\Database $databaseHandler */
|
||||
/** @var \App\Services\Database\Database $databaseHandler */
|
||||
$databaseHandler = $service->handler();
|
||||
$databaseHandler->restoreBackup($backupFile, $database->name);
|
||||
$backupFile->status = BackupFileStatus::RESTORED;
|
||||
|
@ -7,7 +7,7 @@
|
||||
use App\Models\Backup;
|
||||
use App\Models\BackupFile;
|
||||
use App\Models\Service;
|
||||
use App\SSH\Services\Database\Database;
|
||||
use App\Services\Database\Database;
|
||||
use Illuminate\Support\Str;
|
||||
|
||||
class RunBackup
|
||||
|
@ -5,14 +5,15 @@
|
||||
use App\Enums\DatabaseUserStatus;
|
||||
use App\Models\DatabaseUser;
|
||||
use App\Models\Server;
|
||||
use App\SSH\Services\Database\Database;
|
||||
use App\Models\Service;
|
||||
use App\Services\Database\Database;
|
||||
|
||||
class SyncDatabaseUsers
|
||||
{
|
||||
public function sync(Server $server): void
|
||||
{
|
||||
$service = $server->database();
|
||||
if (! $service instanceof \App\Models\Service) {
|
||||
if (! $service instanceof Service) {
|
||||
return;
|
||||
}
|
||||
/** @var Database $handler */
|
||||
|
@ -5,14 +5,14 @@
|
||||
use App\Enums\DatabaseStatus;
|
||||
use App\Models\Server;
|
||||
use App\Models\Service;
|
||||
use App\SSH\Services\Database\Database;
|
||||
use App\Services\Database\Database;
|
||||
|
||||
class SyncDatabases
|
||||
{
|
||||
public function sync(Server $server): void
|
||||
{
|
||||
$service = $server->database();
|
||||
if (! $service instanceof \App\Models\Service) {
|
||||
if (! $service instanceof Service) {
|
||||
return;
|
||||
}
|
||||
/** @var Database $handler */
|
||||
|
@ -6,7 +6,7 @@
|
||||
use App\Models\FirewallRule;
|
||||
use App\Models\Server;
|
||||
use App\Models\Service;
|
||||
use App\SSH\Services\Firewall\Firewall;
|
||||
use App\Services\Firewall\Firewall;
|
||||
use Exception;
|
||||
use Illuminate\Support\Facades\Validator;
|
||||
|
||||
|
@ -9,6 +9,7 @@
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Support\Facades\Validator;
|
||||
use Illuminate\Validation\Rule;
|
||||
use stdClass;
|
||||
|
||||
class GetMetrics
|
||||
{
|
||||
@ -70,7 +71,7 @@ private function metrics(
|
||||
->groupByRaw('date_interval')
|
||||
->orderBy('date_interval')
|
||||
->get()
|
||||
->map(function ($item): \stdClass {
|
||||
->map(function ($item): stdClass {
|
||||
$item->date = Carbon::parse($item->date)->format('Y-m-d H:i');
|
||||
|
||||
return $item;
|
||||
|
@ -4,7 +4,7 @@
|
||||
|
||||
use App\Models\Server;
|
||||
use App\Models\Service;
|
||||
use App\SSH\Services\ServiceInterface;
|
||||
use App\Services\ServiceInterface;
|
||||
use Illuminate\Support\Facades\Validator;
|
||||
|
||||
class UpdateMetricSettings
|
||||
|
@ -6,7 +6,7 @@
|
||||
use App\Exceptions\SSHError;
|
||||
use App\Models\Server;
|
||||
use App\Models\Service;
|
||||
use App\SSH\Services\NodeJS\NodeJS;
|
||||
use App\Services\NodeJS\NodeJS;
|
||||
use Illuminate\Validation\ValidationException;
|
||||
|
||||
class ChangeDefaultCli
|
||||
|
@ -4,6 +4,7 @@
|
||||
|
||||
use App\Models\NotificationChannel;
|
||||
use App\Models\User;
|
||||
use App\NotificationChannels\Email;
|
||||
use Exception;
|
||||
use Illuminate\Support\Facades\Validator;
|
||||
use Illuminate\Validation\Rule;
|
||||
@ -33,7 +34,7 @@ public function add(User $user, array $input): void
|
||||
if (! $channel->provider()->connect()) {
|
||||
$channel->delete();
|
||||
|
||||
if ($channel->provider === \App\Enums\NotificationChannel::EMAIL) {
|
||||
if ($channel->provider === Email::id()) {
|
||||
throw ValidationException::withMessages([
|
||||
'email' => __('Could not connect! Make sure you configured `.env` file correctly.'),
|
||||
]);
|
||||
@ -64,7 +65,7 @@ public static function rules(array $input): array
|
||||
$rules = [
|
||||
'provider' => [
|
||||
'required',
|
||||
Rule::in(config('core.notification_channels_providers')),
|
||||
Rule::in(array_keys(config('notification-channel.providers'))),
|
||||
],
|
||||
'name' => 'required',
|
||||
];
|
||||
|
@ -6,7 +6,7 @@
|
||||
use App\Exceptions\SSHError;
|
||||
use App\Models\Server;
|
||||
use App\Models\Service;
|
||||
use App\SSH\Services\PHP\PHP;
|
||||
use App\Services\PHP\PHP;
|
||||
use Illuminate\Validation\ValidationException;
|
||||
|
||||
class ChangeDefaultCli
|
||||
|
@ -5,7 +5,7 @@
|
||||
use App\Enums\PHPIniType;
|
||||
use App\Models\Server;
|
||||
use App\Models\Service;
|
||||
use App\SSH\Services\PHP\PHP;
|
||||
use App\Services\PHP\PHP;
|
||||
use Illuminate\Support\Facades\Validator;
|
||||
use Illuminate\Validation\Rule;
|
||||
use Illuminate\Validation\ValidationException;
|
||||
|
@ -4,7 +4,7 @@
|
||||
|
||||
use App\Models\Server;
|
||||
use App\Models\Service;
|
||||
use App\SSH\Services\PHP\PHP;
|
||||
use App\Services\PHP\PHP;
|
||||
use Illuminate\Support\Facades\Validator;
|
||||
use Illuminate\Validation\Rule;
|
||||
use Illuminate\Validation\ValidationException;
|
||||
@ -57,7 +57,7 @@ public static function rules(Server $server): array
|
||||
return [
|
||||
'extension' => [
|
||||
'required',
|
||||
Rule::in(config('core.php_extensions')),
|
||||
Rule::in(config('service.services.php.data.extensions', []) ?? []),
|
||||
],
|
||||
'version' => [
|
||||
'required',
|
||||
|
@ -6,7 +6,7 @@
|
||||
use App\Models\Redirect;
|
||||
use App\Models\Service;
|
||||
use App\Models\Site;
|
||||
use App\SSH\Services\Webserver\Webserver;
|
||||
use App\Services\Webserver\Webserver;
|
||||
use Illuminate\Support\Facades\Validator;
|
||||
use Illuminate\Validation\Rule;
|
||||
|
||||
@ -33,7 +33,9 @@ public function create(Site $site, array $input): Redirect
|
||||
$service = $site->server->webserver();
|
||||
/** @var Webserver $webserver */
|
||||
$webserver = $service->handler();
|
||||
$webserver->updateVHost($site);
|
||||
$webserver->updateVHost($site, regenerate: [
|
||||
'redirects',
|
||||
]);
|
||||
$redirect->status = RedirectStatus::READY;
|
||||
$redirect->save();
|
||||
})
|
||||
|
@ -6,7 +6,7 @@
|
||||
use App\Models\Redirect;
|
||||
use App\Models\Service;
|
||||
use App\Models\Site;
|
||||
use App\SSH\Services\Webserver\Webserver;
|
||||
use App\Services\Webserver\Webserver;
|
||||
|
||||
class DeleteRedirect
|
||||
{
|
||||
@ -20,7 +20,9 @@ public function delete(Site $site, Redirect $redirect): void
|
||||
$service = $site->server->webserver();
|
||||
/** @var Webserver $webserver */
|
||||
$webserver = $service->handler();
|
||||
$webserver->updateVHost($site);
|
||||
$webserver->updateVHost($site, regenerate: [
|
||||
'redirects',
|
||||
]);
|
||||
$redirect->delete();
|
||||
})->catch(function () use ($redirect): void {
|
||||
$redirect->status = RedirectStatus::FAILED;
|
||||
|
@ -11,6 +11,8 @@ public function activate(Ssl $ssl): void
|
||||
$ssl->site->ssls()->update(['is_active' => false]);
|
||||
$ssl->is_active = true;
|
||||
$ssl->save();
|
||||
$ssl->site->webserver()->updateVHost($ssl->site);
|
||||
$ssl->site->webserver()->updateVHost($ssl->site, regenerate: [
|
||||
'port',
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
@ -8,7 +8,7 @@
|
||||
use App\Models\Service;
|
||||
use App\Models\Site;
|
||||
use App\Models\Ssl;
|
||||
use App\SSH\Services\Webserver\Webserver;
|
||||
use App\Services\Webserver\Webserver;
|
||||
use Illuminate\Support\Facades\Validator;
|
||||
use Illuminate\Validation\Rule;
|
||||
use Illuminate\Validation\ValidationException;
|
||||
@ -54,7 +54,9 @@ public function create(Site $site, array $input): void
|
||||
$webserver->setupSSL($ssl);
|
||||
$ssl->status = SslStatus::CREATED;
|
||||
$ssl->save();
|
||||
$webserver->updateVHost($site);
|
||||
$webserver->updateVHost($site, regenerate: [
|
||||
'port',
|
||||
]);
|
||||
})->catch(function () use ($ssl): void {
|
||||
$ssl->status = SslStatus::FAILED;
|
||||
$ssl->save();
|
||||
|
@ -10,6 +10,8 @@ public function deactivate(Ssl $ssl): void
|
||||
{
|
||||
$ssl->is_active = false;
|
||||
$ssl->save();
|
||||
$ssl->site->webserver()->updateVHost($ssl->site);
|
||||
$ssl->site->webserver()->updateVHost($ssl->site, regenerate: [
|
||||
'port',
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
@ -5,7 +5,7 @@
|
||||
use App\Enums\SslStatus;
|
||||
use App\Models\Service;
|
||||
use App\Models\Ssl;
|
||||
use App\SSH\Services\Webserver\Webserver;
|
||||
use App\Services\Webserver\Webserver;
|
||||
|
||||
class DeleteSSL
|
||||
{
|
||||
|
@ -3,16 +3,13 @@
|
||||
namespace App\Actions\Server;
|
||||
|
||||
use App\Enums\FirewallRuleStatus;
|
||||
use App\Enums\ServerProvider;
|
||||
use App\Enums\ServerStatus;
|
||||
use App\Enums\ServerType;
|
||||
use App\Exceptions\SSHConnectionError;
|
||||
use App\Facades\Notifier;
|
||||
use App\Models\Project;
|
||||
use App\Models\Server;
|
||||
use App\Models\User;
|
||||
use App\Notifications\ServerInstallationFailed;
|
||||
use App\Notifications\ServerInstallationSucceed;
|
||||
use App\ServerProviders\Custom;
|
||||
use App\ValidationRules\RestrictedIPAddressesRule;
|
||||
use Exception;
|
||||
use Illuminate\Database\Query\Builder;
|
||||
@ -25,6 +22,8 @@
|
||||
|
||||
class CreateServer
|
||||
{
|
||||
protected Server $server;
|
||||
|
||||
/**
|
||||
* @param array<string, mixed> $input
|
||||
*/
|
||||
@ -32,15 +31,14 @@ public function create(User $creator, Project $project, array $input): Server
|
||||
{
|
||||
Validator::make($input, self::rules($project, $input))->validate();
|
||||
|
||||
$server = new Server([
|
||||
$this->server = new Server([
|
||||
'project_id' => $project->id,
|
||||
'user_id' => $creator->id,
|
||||
'name' => $input['name'],
|
||||
'ssh_user' => config('core.server_providers_default_user')[$input['provider']][$input['os']],
|
||||
'ssh_user' => data_get(config('server-provider.providers'), $input['provider'].'.default_user') ?? 'root',
|
||||
'ip' => $input['ip'] ?? '',
|
||||
'port' => $input['port'] ?? 22,
|
||||
'os' => $input['os'],
|
||||
'type' => ServerType::REGULAR,
|
||||
'provider' => $input['provider'],
|
||||
'authentication' => [
|
||||
'user' => config('core.ssh_user'),
|
||||
@ -52,32 +50,42 @@ public function create(User $creator, Project $project, array $input): Server
|
||||
]);
|
||||
|
||||
try {
|
||||
if ($server->provider != 'custom') {
|
||||
$server->provider_id = $input['server_provider'];
|
||||
if ($this->server->provider != 'custom') {
|
||||
$this->server->provider_id = $input['server_provider'];
|
||||
}
|
||||
|
||||
$server->type_data = $server->type()->data($input);
|
||||
|
||||
$server->provider_data = $server->provider()->data($input);
|
||||
$this->server->provider_data = $this->server->provider()->data($input);
|
||||
|
||||
// save
|
||||
$server->save();
|
||||
$this->server->save();
|
||||
|
||||
// create firewall rules
|
||||
$this->createFirewallRules($server);
|
||||
$this->createFirewallRules($this->server);
|
||||
|
||||
// create instance
|
||||
$server->provider()->create();
|
||||
$this->server->provider()->create();
|
||||
|
||||
// add services
|
||||
$server->type()->createServices($input);
|
||||
// create services
|
||||
$this->createServices();
|
||||
|
||||
// install server
|
||||
$this->install($server);
|
||||
dispatch(function (): void {
|
||||
app(InstallServer::class)->run($this->server);
|
||||
})
|
||||
->catch(function (Throwable $e): void {
|
||||
$this->server->update([
|
||||
'status' => ServerStatus::INSTALLATION_FAILED,
|
||||
]);
|
||||
Notifier::send($this->server, new ServerInstallationFailed($this->server));
|
||||
Log::error('server-installation-error', [
|
||||
'error' => (string) $e,
|
||||
]);
|
||||
})
|
||||
->onConnection('ssh');
|
||||
|
||||
return $server;
|
||||
return $this->server;
|
||||
} catch (Exception $e) {
|
||||
$server->delete();
|
||||
$this->server->delete();
|
||||
|
||||
throw ValidationException::withMessages([
|
||||
'provider' => $e->getMessage(),
|
||||
@ -85,41 +93,6 @@ public function create(User $creator, Project $project, array $input): Server
|
||||
}
|
||||
}
|
||||
|
||||
private function install(Server $server): void
|
||||
{
|
||||
dispatch(function () use ($server): void {
|
||||
$maxWait = 180;
|
||||
while ($maxWait > 0) {
|
||||
sleep(10);
|
||||
$maxWait -= 10;
|
||||
if (! $server->provider()->isRunning()) {
|
||||
continue;
|
||||
}
|
||||
try {
|
||||
$server->ssh()->connect();
|
||||
break;
|
||||
} catch (SSHConnectionError) {
|
||||
// ignore
|
||||
}
|
||||
}
|
||||
$server->type()->install();
|
||||
$server->update([
|
||||
'status' => ServerStatus::READY,
|
||||
]);
|
||||
Notifier::send($server, new ServerInstallationSucceed($server));
|
||||
})
|
||||
->catch(function (Throwable $e) use ($server): void {
|
||||
$server->update([
|
||||
'status' => ServerStatus::INSTALLATION_FAILED,
|
||||
]);
|
||||
Notifier::send($server, new ServerInstallationFailed($server));
|
||||
Log::error('server-installation-error', [
|
||||
'error' => (string) $e,
|
||||
]);
|
||||
})
|
||||
->onConnection('ssh');
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array<string, mixed> $input
|
||||
* @return array<string, mixed>
|
||||
@ -129,7 +102,7 @@ public static function rules(Project $project, array $input): array
|
||||
$rules = [
|
||||
'provider' => [
|
||||
'required',
|
||||
Rule::in(config('core.server_providers')),
|
||||
Rule::in(array_keys(config('server-provider.providers'))),
|
||||
],
|
||||
'name' => [
|
||||
'required',
|
||||
@ -139,7 +112,7 @@ public static function rules(Project $project, array $input): array
|
||||
Rule::in(config('core.operating_systems')),
|
||||
],
|
||||
'server_provider' => [
|
||||
Rule::when(fn (): bool => isset($input['provider']) && $input['provider'] != ServerProvider::CUSTOM, [
|
||||
Rule::when(fn (): bool => isset($input['provider']) && $input['provider'] != Custom::id(), [
|
||||
'required',
|
||||
Rule::exists('server_providers', 'id')->where(function (Builder $query) use ($project): void {
|
||||
$query->where('project_id', $project->id)
|
||||
@ -148,13 +121,13 @@ public static function rules(Project $project, array $input): array
|
||||
]),
|
||||
],
|
||||
'ip' => [
|
||||
Rule::when(fn (): bool => isset($input['provider']) && $input['provider'] == ServerProvider::CUSTOM, [
|
||||
Rule::when(fn (): bool => isset($input['provider']) && $input['provider'] == Custom::id(), [
|
||||
'required',
|
||||
new RestrictedIPAddressesRule,
|
||||
]),
|
||||
],
|
||||
'port' => [
|
||||
Rule::when(fn (): bool => isset($input['provider']) && $input['provider'] == ServerProvider::CUSTOM, [
|
||||
Rule::when(fn (): bool => isset($input['provider']) && $input['provider'] == Custom::id(), [
|
||||
'required',
|
||||
'numeric',
|
||||
'min:1',
|
||||
@ -163,22 +136,7 @@ public static function rules(Project $project, array $input): array
|
||||
],
|
||||
];
|
||||
|
||||
return array_merge($rules, self::typeRules($input), self::providerRules($input));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array<string, mixed> $input
|
||||
* @return array<string, array<string>>
|
||||
*/
|
||||
private static function typeRules(array $input): array
|
||||
{
|
||||
if (! isset($input['type']) || ! in_array($input['type'], config('core.server_types'))) {
|
||||
return [];
|
||||
}
|
||||
|
||||
$server = new Server(['type' => $input['type']]);
|
||||
|
||||
return $server->type()->createRules($input);
|
||||
return array_merge($rules, self::providerRules($input));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -190,8 +148,8 @@ private static function providerRules(array $input): array
|
||||
if (
|
||||
! isset($input['provider']) ||
|
||||
! isset($input['server_provider']) ||
|
||||
! in_array($input['provider'], config('core.server_providers')) ||
|
||||
$input['provider'] == ServerProvider::CUSTOM
|
||||
! config('server-provider.providers.'.$input['provider']) ||
|
||||
$input['provider'] == Custom::id()
|
||||
) {
|
||||
return [];
|
||||
}
|
||||
@ -236,4 +194,49 @@ public function createFirewallRules(Server $server): void
|
||||
],
|
||||
]);
|
||||
}
|
||||
|
||||
private function createServices(): void
|
||||
{
|
||||
$this->server->services()->forceDelete();
|
||||
$this->addSupervisor();
|
||||
$this->addRedis();
|
||||
$this->addUfw();
|
||||
$this->addMonitoring();
|
||||
}
|
||||
|
||||
private function addSupervisor(): void
|
||||
{
|
||||
$this->server->services()->create([
|
||||
'type' => 'process_manager',
|
||||
'name' => 'supervisor',
|
||||
'version' => 'latest',
|
||||
]);
|
||||
}
|
||||
|
||||
private function addRedis(): void
|
||||
{
|
||||
$this->server->services()->create([
|
||||
'type' => 'memory_database',
|
||||
'name' => 'redis',
|
||||
'version' => 'latest',
|
||||
]);
|
||||
}
|
||||
|
||||
private function addUfw(): void
|
||||
{
|
||||
$this->server->services()->create([
|
||||
'type' => 'firewall',
|
||||
'name' => 'ufw',
|
||||
'version' => 'latest',
|
||||
]);
|
||||
}
|
||||
|
||||
private function addMonitoring(): void
|
||||
{
|
||||
$this->server->services()->create([
|
||||
'type' => 'monitoring',
|
||||
'name' => 'remote-monitor',
|
||||
'version' => 'latest',
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
97
app/Actions/Server/InstallServer.php
Normal file
97
app/Actions/Server/InstallServer.php
Normal file
@ -0,0 +1,97 @@
|
||||
<?php
|
||||
|
||||
namespace App\Actions\Server;
|
||||
|
||||
use App\Enums\ServerStatus;
|
||||
use App\Enums\ServiceStatus;
|
||||
use App\Exceptions\SSHConnectionError;
|
||||
use App\Exceptions\SSHError;
|
||||
use App\Facades\Notifier;
|
||||
use App\Models\Server;
|
||||
use App\Notifications\ServerInstallationSucceed;
|
||||
use App\Services\PHP\PHP;
|
||||
|
||||
class InstallServer
|
||||
{
|
||||
protected Server $server;
|
||||
|
||||
/**
|
||||
* @throws SSHError
|
||||
*/
|
||||
public function run(Server $server): void
|
||||
{
|
||||
$this->server = $server;
|
||||
|
||||
$maxWait = 180;
|
||||
while ($maxWait > 0) {
|
||||
if (! $this->server->provider()->isRunning()) {
|
||||
continue;
|
||||
}
|
||||
try {
|
||||
$this->server->ssh()->connect();
|
||||
break;
|
||||
} catch (SSHConnectionError) {
|
||||
// ignore
|
||||
}
|
||||
sleep(10);
|
||||
$maxWait -= 10;
|
||||
}
|
||||
$this->install();
|
||||
$this->server->update([
|
||||
'status' => ServerStatus::READY,
|
||||
]);
|
||||
Notifier::send($this->server, new ServerInstallationSucceed($this->server));
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws SSHError
|
||||
*/
|
||||
public function install(): void
|
||||
{
|
||||
$this->createUser();
|
||||
$this->progress(15, 'installing-updates');
|
||||
$this->server->os()->upgrade();
|
||||
$this->progress(25, 'installing-dependencies');
|
||||
$this->server->os()->installDependencies();
|
||||
$services = $this->server->services;
|
||||
$currentProgress = 45;
|
||||
$progressPerService = (100 - $currentProgress) / count($services);
|
||||
foreach ($services as $service) {
|
||||
$currentProgress += $progressPerService;
|
||||
$this->progress($currentProgress, 'installing- '.$service->name);
|
||||
$service->handler()->install();
|
||||
$service->update(['status' => ServiceStatus::READY]);
|
||||
if ($service->type == 'php') {
|
||||
$this->progress($currentProgress, 'installing-composer');
|
||||
/** @var PHP $handler */
|
||||
$handler = $service->handler();
|
||||
$handler->installComposer();
|
||||
}
|
||||
}
|
||||
$this->progress(100, 'finishing');
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws SSHError
|
||||
*/
|
||||
protected function createUser(): void
|
||||
{
|
||||
$this->server->os()->createUser(
|
||||
$this->server->authentication['user'],
|
||||
$this->server->authentication['pass'],
|
||||
$this->server->sshKey()['public_key']
|
||||
);
|
||||
$this->server->ssh_user = config('core.ssh_user');
|
||||
$this->server->save();
|
||||
$this->server->refresh();
|
||||
$this->server->public_key = $this->server->os()->getPublicKey($this->server->getSshUser());
|
||||
$this->server->save();
|
||||
}
|
||||
|
||||
protected function progress(int|float $percentage, ?string $step = null): void
|
||||
{
|
||||
$this->server->progress = $percentage;
|
||||
$this->server->progress_step = $step;
|
||||
$this->server->save();
|
||||
}
|
||||
}
|
@ -48,7 +48,7 @@ public function create(User $user, Project $project, array $input): ServerProvid
|
||||
|
||||
private static function getProvider(string $name): ServerProviderContract
|
||||
{
|
||||
$providerClass = config('core.server_providers_class.'.$name);
|
||||
$providerClass = config('server-provider.providers.'.$name.'.handler');
|
||||
/** @var ServerProviderContract $provider */
|
||||
$provider = new $providerClass(new ServerProvider, new Server);
|
||||
|
||||
@ -67,7 +67,7 @@ public static function rules(array $input): array
|
||||
],
|
||||
'provider' => [
|
||||
'required',
|
||||
Rule::in(config('core.server_providers')),
|
||||
Rule::in(array_keys(config('server-provider.providers'))),
|
||||
Rule::notIn('custom'),
|
||||
],
|
||||
];
|
||||
|
@ -17,7 +17,12 @@ public function install(Server $server, array $input): Service
|
||||
{
|
||||
Validator::make($input, self::rules($input))->validate();
|
||||
|
||||
$input['type'] = config('core.service_types')[$input['name']];
|
||||
$name = $input['name'];
|
||||
$input['type'] = config("service.services.$name.type");
|
||||
|
||||
if (! $input['type']) {
|
||||
throw new \InvalidArgumentException("Service type is not defined for $name");
|
||||
}
|
||||
|
||||
$service = new Service([
|
||||
'server_id' => $server->id,
|
||||
@ -55,14 +60,14 @@ public static function rules(array $input): array
|
||||
$rules = [
|
||||
'name' => [
|
||||
'required',
|
||||
Rule::in(array_keys(config('core.service_types'))),
|
||||
Rule::in(array_keys(config('service.services'))),
|
||||
],
|
||||
'version' => [
|
||||
'required',
|
||||
],
|
||||
];
|
||||
if (isset($input['name'])) {
|
||||
$rules['version'][] = Rule::in(config("core.service_versions.{$input['name']}"));
|
||||
$rules['version'][] = Rule::in(config("service.services.{$input['name']}.versions", []));
|
||||
}
|
||||
|
||||
return $rules;
|
||||
|
@ -4,15 +4,17 @@
|
||||
|
||||
use App\Enums\ServiceStatus;
|
||||
use App\Models\Service;
|
||||
use Illuminate\Validation\ValidationException;
|
||||
|
||||
class Manage
|
||||
{
|
||||
public function start(Service $service): void
|
||||
{
|
||||
$this->validate($service);
|
||||
$service->status = ServiceStatus::STARTING;
|
||||
$service->save();
|
||||
dispatch(function () use ($service): void {
|
||||
$status = $service->server->systemd()->start($service->unit);
|
||||
$status = $service->server->systemd()->start($service->handler()->unit());
|
||||
if (str($status)->contains('Active: active')) {
|
||||
$service->status = ServiceStatus::READY;
|
||||
} else {
|
||||
@ -24,10 +26,11 @@ public function start(Service $service): void
|
||||
|
||||
public function stop(Service $service): void
|
||||
{
|
||||
$this->validate($service);
|
||||
$service->status = ServiceStatus::STOPPING;
|
||||
$service->save();
|
||||
dispatch(function () use ($service): void {
|
||||
$status = $service->server->systemd()->stop($service->unit);
|
||||
$status = $service->server->systemd()->stop($service->handler()->unit());
|
||||
if (str($status)->contains('Active: inactive')) {
|
||||
$service->status = ServiceStatus::STOPPED;
|
||||
} else {
|
||||
@ -39,10 +42,11 @@ public function stop(Service $service): void
|
||||
|
||||
public function restart(Service $service): void
|
||||
{
|
||||
$this->validate($service);
|
||||
$service->status = ServiceStatus::RESTARTING;
|
||||
$service->save();
|
||||
dispatch(function () use ($service): void {
|
||||
$status = $service->server->systemd()->restart($service->unit);
|
||||
$status = $service->server->systemd()->restart($service->handler()->unit());
|
||||
if (str($status)->contains('Active: active')) {
|
||||
$service->status = ServiceStatus::READY;
|
||||
} else {
|
||||
@ -54,10 +58,11 @@ public function restart(Service $service): void
|
||||
|
||||
public function enable(Service $service): void
|
||||
{
|
||||
$this->validate($service);
|
||||
$service->status = ServiceStatus::ENABLING;
|
||||
$service->save();
|
||||
dispatch(function () use ($service): void {
|
||||
$status = $service->server->systemd()->enable($service->unit);
|
||||
$status = $service->server->systemd()->enable($service->handler()->unit());
|
||||
if (str($status)->contains('Active: active')) {
|
||||
$service->status = ServiceStatus::READY;
|
||||
} else {
|
||||
@ -69,10 +74,11 @@ public function enable(Service $service): void
|
||||
|
||||
public function disable(Service $service): void
|
||||
{
|
||||
$this->validate($service);
|
||||
$service->status = ServiceStatus::DISABLING;
|
||||
$service->save();
|
||||
dispatch(function () use ($service): void {
|
||||
$status = $service->server->systemd()->disable($service->unit);
|
||||
$status = $service->server->systemd()->disable($service->handler()->unit());
|
||||
if (str($status)->contains('Active: inactive')) {
|
||||
$service->status = ServiceStatus::DISABLED;
|
||||
} else {
|
||||
@ -81,4 +87,13 @@ public function disable(Service $service): void
|
||||
$service->save();
|
||||
})->onConnection('ssh');
|
||||
}
|
||||
|
||||
private function validate(Service $service): void
|
||||
{
|
||||
if (! $service->handler()->unit()) {
|
||||
throw ValidationException::withMessages([
|
||||
'service' => __('This service does not have a systemd unit configured.'),
|
||||
]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -13,7 +13,6 @@
|
||||
use App\Notifications\SiteInstallationSucceed;
|
||||
use App\ValidationRules\DomainRule;
|
||||
use Exception;
|
||||
use Illuminate\Database\Query\Builder;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Support\Facades\Validator;
|
||||
use Illuminate\Validation\Rule;
|
||||
@ -39,7 +38,6 @@ public function create(Server $server, array $input): Site
|
||||
'type' => $input['type'],
|
||||
'domain' => $input['domain'],
|
||||
'aliases' => $input['aliases'] ?? [],
|
||||
'port' => $input['port'] ?? null,
|
||||
'user' => $user,
|
||||
'path' => '/home/'.$user.'/'.$input['domain'],
|
||||
'status' => SiteStatus::INSTALLING,
|
||||
@ -116,7 +114,7 @@ public static function rules(Server $server, array $input): array
|
||||
$rules = [
|
||||
'type' => [
|
||||
'required',
|
||||
Rule::in(config('core.site_types')),
|
||||
Rule::in(array_keys(config('site.types'))),
|
||||
],
|
||||
'domain' => [
|
||||
'required',
|
||||
@ -134,14 +132,6 @@ public static function rules(Server $server, array $input): array
|
||||
Rule::unique('sites', 'user')->where('server_id', $server->id),
|
||||
Rule::notIn($server->getSshUsers()),
|
||||
],
|
||||
'port' => [
|
||||
'nullable',
|
||||
'integer',
|
||||
'min:1',
|
||||
'max:65535',
|
||||
Rule::unique('sites', 'port')
|
||||
->where(fn (Builder $query) => $query->where('server_id', $server->id)),
|
||||
],
|
||||
];
|
||||
|
||||
return array_merge($rules, self::typeRules($server, $input));
|
||||
@ -153,7 +143,7 @@ public static function rules(Server $server, array $input): array
|
||||
*/
|
||||
private static function typeRules(Server $server, array $input): array
|
||||
{
|
||||
if (! isset($input['type']) || ! in_array($input['type'], config('core.site_types'))) {
|
||||
if (! isset($input['type']) || ! config('site.types.'.$input['type'])) {
|
||||
return [];
|
||||
}
|
||||
|
||||
|
@ -5,8 +5,8 @@
|
||||
use App\Exceptions\SSHError;
|
||||
use App\Models\Service;
|
||||
use App\Models\Site;
|
||||
use App\SSH\Services\PHP\PHP;
|
||||
use App\SSH\Services\Webserver\Webserver;
|
||||
use App\Services\PHP\PHP;
|
||||
use App\Services\Webserver\Webserver;
|
||||
use Illuminate\Support\Facades\Validator;
|
||||
use Illuminate\Validation\Rule;
|
||||
|
||||
|
@ -4,7 +4,7 @@
|
||||
|
||||
use App\Models\Service;
|
||||
use App\Models\Site;
|
||||
use App\SSH\Services\Webserver\Webserver;
|
||||
use App\Services\Webserver\Webserver;
|
||||
use App\ValidationRules\DomainRule;
|
||||
|
||||
class UpdateAliases
|
||||
@ -21,7 +21,9 @@ public function update(Site $site, array $input): void
|
||||
|
||||
/** @var Webserver $webserver */
|
||||
$webserver = $service->handler();
|
||||
$webserver->updateVHost($site);
|
||||
$webserver->updateVHost($site, regenerate: [
|
||||
'core',
|
||||
]);
|
||||
|
||||
$site->save();
|
||||
}
|
||||
|
@ -4,7 +4,7 @@
|
||||
|
||||
use App\Exceptions\SSHError;
|
||||
use App\Models\Site;
|
||||
use App\SSH\Git\Git;
|
||||
use App\SSH\OS\Git;
|
||||
use Illuminate\Support\Facades\Validator;
|
||||
|
||||
class UpdateBranch
|
||||
|
@ -30,7 +30,10 @@ public function update(Site $site, array $input): void
|
||||
$loadBalancerServer->save();
|
||||
}
|
||||
|
||||
$site->webserver()->updateVHost($site);
|
||||
$site->webserver()->updateVHost($site, regenerate: [
|
||||
'load-balancer-upstream',
|
||||
'load-balancer',
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -51,7 +51,7 @@ public static function rules(array $input): array
|
||||
],
|
||||
'provider' => [
|
||||
'required',
|
||||
Rule::in(config('core.source_control_providers')),
|
||||
Rule::in(array_keys(config('source-control.providers'))),
|
||||
],
|
||||
];
|
||||
|
||||
|
@ -8,6 +8,7 @@
|
||||
use Illuminate\Support\Facades\Validator;
|
||||
use Illuminate\Validation\Rule;
|
||||
use Illuminate\Validation\ValidationException;
|
||||
use Throwable;
|
||||
|
||||
class CreateStorageProvider
|
||||
{
|
||||
@ -35,7 +36,7 @@ public function create(User $user, Project $project, array $input): StorageProvi
|
||||
'provider' => __("Couldn't connect to the provider"),
|
||||
]);
|
||||
}
|
||||
} catch (\Throwable $e) {
|
||||
} catch (Throwable $e) {
|
||||
throw ValidationException::withMessages([
|
||||
'provider' => $e->getMessage(),
|
||||
]);
|
||||
@ -55,7 +56,7 @@ public static function rules(array $input): array
|
||||
$rules = [
|
||||
'provider' => [
|
||||
'required',
|
||||
Rule::in(config('core.storage_providers')),
|
||||
Rule::in(array_keys(config('storage-provider.providers'))),
|
||||
],
|
||||
'name' => [
|
||||
'required',
|
||||
|
@ -7,7 +7,7 @@
|
||||
use App\Models\Service;
|
||||
use App\Models\Site;
|
||||
use App\Models\Worker;
|
||||
use App\SSH\Services\ProcessManager\ProcessManager;
|
||||
use App\Services\ProcessManager\ProcessManager;
|
||||
use Illuminate\Support\Facades\Validator;
|
||||
use Illuminate\Validation\Rule;
|
||||
use Illuminate\Validation\ValidationException;
|
||||
@ -26,6 +26,7 @@ public function create(Server $server, array $input, ?Site $site = null): void
|
||||
$worker = new Worker([
|
||||
'server_id' => $server->id,
|
||||
'site_id' => $site?->id,
|
||||
'name' => $input['name'],
|
||||
'command' => $input['command'],
|
||||
'user' => $input['user'],
|
||||
'auto_start' => $input['auto_start'] ? 1 : 0,
|
||||
@ -63,6 +64,19 @@ public function create(Server $server, array $input, ?Site $site = null): void
|
||||
public static function rules(Server $server, ?Site $site = null): array
|
||||
{
|
||||
return [
|
||||
'name' => [
|
||||
'required',
|
||||
'string',
|
||||
'max:255',
|
||||
Rule::unique('workers')->where(function ($query) use ($server, $site) {
|
||||
return $query->where('server_id', $server->id)
|
||||
->where(function ($query) use ($site) {
|
||||
if ($site) {
|
||||
$query->where('site_id', $site->id);
|
||||
}
|
||||
});
|
||||
}),
|
||||
],
|
||||
'command' => [
|
||||
'required',
|
||||
],
|
||||
|
@ -3,11 +3,10 @@
|
||||
namespace App\Actions\Worker;
|
||||
|
||||
use App\Enums\WorkerStatus;
|
||||
use App\Models\Server;
|
||||
use App\Models\Service;
|
||||
use App\Models\Site;
|
||||
use App\Models\Worker;
|
||||
use App\SSH\Services\ProcessManager\ProcessManager;
|
||||
use App\Services\ProcessManager\ProcessManager;
|
||||
use Illuminate\Support\Facades\Validator;
|
||||
use Illuminate\Validation\Rule;
|
||||
use Illuminate\Validation\ValidationException;
|
||||
@ -21,9 +20,10 @@ class EditWorker
|
||||
*/
|
||||
public function edit(Worker $worker, array $input): void
|
||||
{
|
||||
Validator::make($input, self::rules($worker->server, $worker->site))->validate();
|
||||
Validator::make($input, self::rules($worker, $worker->site))->validate();
|
||||
|
||||
$worker->fill([
|
||||
'name' => $input['name'],
|
||||
'command' => $input['command'],
|
||||
'user' => $input['user'],
|
||||
'auto_start' => $input['auto_start'] ? 1 : 0,
|
||||
@ -61,15 +61,29 @@ public function edit(Worker $worker, array $input): void
|
||||
/**
|
||||
* @return array<string, array<string>>
|
||||
*/
|
||||
public static function rules(Server $server, ?Site $site = null): array
|
||||
public static function rules(Worker $worker, ?Site $site = null): array
|
||||
{
|
||||
return [
|
||||
'name' => [
|
||||
'required',
|
||||
'string',
|
||||
'max:255',
|
||||
Rule::unique('workers')->where(function ($query) use ($worker, $site) {
|
||||
return $query->where('server_id', $worker->server_id)
|
||||
->where(function ($query) use ($site) {
|
||||
if ($site) {
|
||||
$query->where('site_id', $site->id);
|
||||
}
|
||||
});
|
||||
})
|
||||
->ignore($worker->id),
|
||||
],
|
||||
'command' => [
|
||||
'required',
|
||||
],
|
||||
'user' => [
|
||||
'required',
|
||||
Rule::in($site?->getSshUsers() ?? $server->getSshUsers()),
|
||||
Rule::in($site?->getSshUsers() ?? $worker->server->getSshUsers()),
|
||||
],
|
||||
'numprocs' => [
|
||||
'required',
|
||||
|
@ -4,7 +4,7 @@
|
||||
|
||||
use App\Models\Service;
|
||||
use App\Models\Worker;
|
||||
use App\SSH\Services\ProcessManager\ProcessManager;
|
||||
use App\Services\ProcessManager\ProcessManager;
|
||||
|
||||
class GetWorkerLogs
|
||||
{
|
||||
|
@ -5,7 +5,7 @@
|
||||
use App\Enums\WorkerStatus;
|
||||
use App\Models\Service;
|
||||
use App\Models\Worker;
|
||||
use App\SSH\Services\ProcessManager\ProcessManager;
|
||||
use App\Services\ProcessManager\ProcessManager;
|
||||
|
||||
class ManageWorker
|
||||
{
|
||||
|
Reference in New Issue
Block a user