add server types

This commit is contained in:
Saeed Vaziry 2023-07-10 12:15:55 +02:00
parent 6f9bba5511
commit d673336ca3
13 changed files with 265 additions and 43 deletions

32
LICENSE Normal file
View File

@ -0,0 +1,32 @@
Business Source License 1.1
Parameters
Licensor: Saeed Vaziry.
Licensed Work: Vito
The Licensed Work is (c) 2023 Saeed Vaziry.
Additional Use Grant: You may make use of the Licensed Work, provided that you do
not use the Licensed Work for a Server Management Service
A "Server Management Service" is a commercial offering
that allows third parties (other than your employees and
contractors) to access the functionality of the Licensed
Work so that such third parties directly benefit from the
server-deployment or server-management features of the
Licensed Work.
Change Date: 2033-07-10
Change License: Apache License, Version 2.0
Notice
The Business Source License (this document, or the "License") is not an Open
Source license. However, the Licensed Work will eventually be made available
under an Open Source License, as stated in this License.
License text copyright (c) 2023 [Your Name/Company Name], All Rights Reserved.
"Business Source License" is a trademark of MariaDB Corporation Ab.
[Remainder of Business Source License 1.1]

View File

@ -1 +1,15 @@
# Vito
## Installation
```shell
curl -o- https://raw.githubusercontent.com/vitodeployer/vito/main/install/install.sh | V_DOMAIN= V_ADMIN_EMAIL= V_ADMIN_PASSWORD= bash
```
Replace the variables and then run the command
```dotenv
V_DOMAIN=domain
V_ADMIN_EMAIL=your-email
V_ADMIN_PASSWORD=your-password
```

View File

@ -7,4 +7,5 @@
final class ServerType extends Enum
{
const REGULAR = 'regular';
const DATABASE = 'database';
}

View File

@ -6,5 +6,7 @@
final class Webserver extends Enum
{
const NONE = 'none';
const NGINX = 'nginx';
}

141
app/ServerTypes/Database.php Executable file
View File

@ -0,0 +1,141 @@
<?php
namespace App\ServerTypes;
use App\Events\Broadcast;
use App\Jobs\Installation\Initialize;
use App\Jobs\Installation\InstallCertbot;
use App\Jobs\Installation\InstallComposer;
use App\Jobs\Installation\InstallNodejs;
use App\Jobs\Installation\InstallRequirements;
use App\Jobs\Installation\Upgrade;
use Illuminate\Support\Facades\Bus;
use Illuminate\Support\Facades\Log;
use Throwable;
class Database extends AbstractType
{
public function createValidationRules(array $input): array
{
return [
'database' => [
'required',
'in:'.implode(',', config('core.databases')),
],
];
}
public function data(array $input): array
{
return [];
}
public function createServices(array $input): void
{
$this->server->services()->forceDelete();
$this->addDatabase($input['database']);
$this->addSupervisor();
$this->addRedis();
$this->addUfw();
}
public function install(): void
{
$jobs = [
new Initialize($this->server, $this->server->ssh_user, $this->server->provider === 'custom'),
$this->progress(15, 'Installing Updates'),
new Upgrade($this->server),
$this->progress(25, 'Installing Requirements'),
new InstallRequirements($this->server),
];
$services = $this->server->services;
$currentProgress = 25;
$progressPerService = (100 - $currentProgress) / count($services);
foreach ($services as $service) {
$currentProgress += $progressPerService;
$jobs[] = $this->progress($currentProgress, 'Installing '.$service->name);
$jobs[] = $service->installer();
}
$jobs[] = function () {
$this->server->update([
'status' => 'ready',
'progress' => 100,
]);
event(
new Broadcast('install-server-finished', [
'server' => $this->server,
])
);
/** @todo notify */
};
Bus::chain($jobs)
->catch(function (Throwable $e) {
$this->server->update([
'status' => 'installation_failed',
]);
event(
new Broadcast('install-server-failed', [
'server' => $this->server,
])
);
/** @todo notify */
Log::error('server-installation-error', [
'error' => (string) $e,
]);
throw $e;
})
->onConnection('ssh-long')
->dispatch();
}
protected function addDatabase(string $service): void
{
if ($service != 'none') {
$this->server->services()->create([
'type' => 'database',
'name' => config('core.databases_name.'.$service),
'version' => config('core.databases_version.'.$service),
]);
}
}
/**
* add supervisor
*/
protected function addSupervisor(): void
{
$this->server->services()->create([
'type' => 'process_manager',
'name' => 'supervisor',
'version' => 'latest',
]);
}
/**
* add supervisor
*/
protected function addRedis(): void
{
$this->server->services()->create([
'type' => 'memory_database',
'name' => 'redis',
'version' => 'latest',
]);
}
/**
* add supervisor
*/
protected function addUfw(): void
{
$this->server->services()->create([
'type' => 'firewall',
'name' => 'ufw',
'version' => 'latest',
]);
}
}

View File

@ -18,7 +18,6 @@
use App\ServerProviders\Hetzner;
use App\ServerProviders\Linode;
use App\ServerProviders\Vultr;
use App\ServerTypes\Regular;
use App\ServiceHandlers\Database\Mysql;
use App\ServiceHandlers\Firewall\Ufw;
use App\ServiceHandlers\PHP;
@ -48,7 +47,7 @@
* General
*/
'operating_systems' => ['ubuntu_18', 'ubuntu_20', 'ubuntu_22'],
'webservers' => ['nginx'],
'webservers' => ['none', 'nginx'],
'php_versions' => [
'none',
// '5.6',
@ -76,18 +75,19 @@
/*
* Server
*/
'server_types' => ['regular'],
'server_types' => \App\Enums\ServerType::getValues(),
'server_types_class' => [
'regular' => Regular::class,
\App\Enums\ServerType::REGULAR => \App\ServerTypes\Regular::class,
\App\Enums\ServerType::DATABASE => \App\ServerTypes\Database::class,
],
'server_providers' => ['custom', 'aws', 'linode', 'digitalocean', 'vultr', 'hetzner'],
'server_providers' => \App\Enums\ServerProvider::getValues(),
'server_providers_class' => [
'custom' => \App\ServerProviders\Custom::class,
'aws' => AWS::class,
'linode' => Linode::class,
'digitalocean' => DigitalOcean::class,
'vultr' => Vultr::class,
'hetzner' => Hetzner::class,
\App\Enums\ServerProvider::CUSTOM => \App\ServerProviders\Custom::class,
\App\Enums\ServerProvider::AWS => AWS::class,
\App\Enums\ServerProvider::LINODE => Linode::class,
\App\Enums\ServerProvider::DIGITALOCEAN => DigitalOcean::class,
\App\Enums\ServerProvider::VULTR => Vultr::class,
\App\Enums\ServerProvider::HETZNER => Hetzner::class,
],
'server_providers_default_user' => [
'custom' => [

View File

@ -115,6 +115,7 @@ mysql -e "GRANT ALL PRIVILEGES ON ${V_DB_NAME}.* TO '${V_DB_USER}'@'localhost'"
mysql -e "FLUSH PRIVILEGES"
# setup website
export V_SSL=1
export COMPOSER_ALLOW_SUPERUSER=1
export V_REPO="https://github.com/vitodeployer/vito.git"
export V_VHOST_CONFIG="
@ -166,7 +167,12 @@ find /home/${V_USERNAME}/${V_DOMAIN} -type f -exec chmod 644 {} \;
cd /home/${V_USERNAME}/${V_DOMAIN} && git config core.fileMode false
cd /home/${V_USERNAME}/${V_DOMAIN} && composer install --no-dev
cp .env.prod .env
sed -i "s|APP_URL=.*|APP_URL=http://${V_DOMAIN}|" /home/${V_USERNAME}/${V_DOMAIN}/.env
if [[ ${V_SSL} == 1 ]]; then
export V_URL="https://${V_DOMAIN}"
else
export V_URL="http://${V_DOMAIN}"
fi
sed -i "s|APP_URL=.*|APP_URL=${V_URL}|" /home/${V_USERNAME}/${V_DOMAIN}/.env
sed -i "s|DB_DATABASE=.*|DB_DATABASE=${V_DB_NAME}|" /home/${V_USERNAME}/${V_DOMAIN}/.env
sed -i "s|DB_USERNAME=.*|DB_USERNAME=${V_DB_USER}|" /home/${V_USERNAME}/${V_DOMAIN}/.env
sed -i "s|DB_PASSWORD=.*|DB_PASSWORD=${V_DB_PASS}|" /home/${V_USERNAME}/${V_DOMAIN}/.env

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -1,6 +1,6 @@
{
"resources/css/app.css": {
"file": "assets/app-268b44f6.css",
"file": "assets/app-0d136492.css",
"isEntry": true,
"src": "resources/css/app.css"
},

View File

@ -10,22 +10,30 @@
<x-heroicon-o-home class="w-6 h-6 mr-1" />
{{ __('Overview') }}
</x-sidebar-link>
@if($server->webserver())
<x-sidebar-link :href="route('servers.sites', ['server' => $server])" :active="request()->routeIs('servers.sites') || request()->is('servers/*/sites/*')">
<x-heroicon-o-globe-alt class="w-6 h-6 mr-1" />
{{ __('Sites') }}
</x-sidebar-link>
@endif
@if($server->database())
<x-sidebar-link :href="route('servers.databases', ['server' => $server])" :active="request()->routeIs('servers.databases')">
<x-heroicon-o-circle-stack class="w-6 h-6 mr-1" />
{{ __('Databases') }}
</x-sidebar-link>
@endif
@if($server->php())
<x-sidebar-link :href="route('servers.php', ['server' => $server])" :active="request()->routeIs('servers.php')">
<x-heroicon-o-code-bracket class="w-6 h-6 mr-1" />
{{ __('PHP') }}
</x-sidebar-link>
@endif
@if($server->firewall())
<x-sidebar-link :href="route('servers.firewall', ['server' => $server])" :active="request()->routeIs('servers.firewall')">
<x-heroicon-o-fire class="w-6 h-6 mr-1" />
{{ __('Firewall') }}
</x-sidebar-link>
@endif
<x-sidebar-link :href="route('servers.cronjobs', ['server' => $server])" :active="request()->routeIs('servers.cronjobs')">
<x-heroicon-o-clock class="w-6 h-6 mr-1" />
{{ __('Cronjobs') }}

View File

@ -115,6 +115,20 @@
@enderror
</div>
<div>
<x-input-label for="type" value="Server Type" />
<x-select-input wire:model.defer="type" id="type" name="type" class="mt-1 w-full">
@foreach(config('core.server_types') as $serverType)
<option value="{{ $serverType }}" @if($type === $serverType) selected @endif>
{{ $serverType }}
</option>
@endforeach
</x-select-input>
@error('type')
<x-input-error class="mt-2" :messages="$message" />
@enderror
</div>
<div class="grid grid-cols-1 lg:grid-cols-3 gap-3">
<div>
<x-input-label for="webserver" value="Webserver" />

View File

@ -8,21 +8,25 @@
@include('livewire.servers.partials.status', ['status' => $server->status])
</x-slot>
</x-card-header>
<div class="mx-auto grid grid-cols-3 rounded-md bg-white border border-gray-200 dark:border-gray-700 dark:bg-gray-800">
<div class="p-5">
<div class="mx-auto grid @if($server->webserver() && $server->database()) grid-cols-3 @else grid-cols-2 @endif rounded-md bg-white border border-gray-200 dark:border-gray-700 dark:bg-gray-800">
@if($server->webserver())
<div class="p-5 border-r border-gray-200 p-5 dark:border-gray-900">
<div class="flex items-center justify-center md:justify-start">
<x-heroicon-o-globe-alt class="w-8 h-8 text-primary-500" />
<div class="ml-2 hidden md:block">{{ __("Sites") }}</div>
</div>
<div class="mt-3 text-center text-3xl font-bold text-gray-600 dark:text-gray-400 md:text-left">{{ $server->sites()->count() }}</div>
</div>
<div class="border-l border-r border-gray-200 p-5 dark:border-gray-900">
@endif
@if($server->database())
<div class="border-r border-gray-200 p-5 dark:border-gray-900">
<div class="flex items-center justify-center md:justify-start">
<x-heroicon-o-circle-stack class="w-8 h-8 text-primary-500" />
<div class="ml-2 hidden md:block">{{ __("Databases") }}</div>
</div>
<div class="mt-3 text-center text-3xl font-bold text-gray-600 dark:text-gray-400 md:text-left">{{ $server->databases()->count() }}</div>
</div>
@endif
<div class="p-5">
<div class="flex items-center justify-center md:justify-start">
<x-heroicon-o-briefcase class="w-8 h-8 text-primary-500" />