coolify/app/Livewire/Boarding/Index.php

364 lines
12 KiB
PHP
Raw Normal View History

2023-08-29 16:31:46 +02:00
<?php
2023-12-07 19:06:32 +01:00
namespace App\Livewire\Boarding;
2023-08-29 20:34:01 +02:00
use App\Enums\ProxyTypes;
2023-08-29 16:31:46 +02:00
use App\Models\PrivateKey;
use App\Models\Project;
use App\Models\Server;
2023-09-08 18:33:26 +02:00
use App\Models\Team;
2023-08-30 11:06:44 +02:00
use Illuminate\Support\Collection;
2023-08-29 16:31:46 +02:00
use Livewire\Component;
class Index extends Component
2023-08-29 20:34:01 +02:00
{
2024-06-18 16:42:42 +02:00
protected $listeners = ['refreshBoardingIndex' => 'validateServer'];
2023-08-29 16:31:46 +02:00
public string $currentState = 'welcome';
2024-03-20 15:46:59 +01:00
public ?string $selectedServerType = null;
2024-06-10 22:43:34 +02:00
2023-08-29 20:34:01 +02:00
public ?Collection $privateKeys = null;
2024-03-20 15:46:59 +01:00
2023-08-29 20:34:01 +02:00
public ?int $selectedExistingPrivateKey = null;
2024-06-10 22:43:34 +02:00
2023-08-29 16:31:46 +02:00
public ?string $privateKeyType = null;
2024-06-10 22:43:34 +02:00
2023-08-29 16:31:46 +02:00
public ?string $privateKey = null;
2024-06-10 22:43:34 +02:00
2023-08-29 16:31:46 +02:00
public ?string $publicKey = null;
2024-06-10 22:43:34 +02:00
2023-08-29 16:31:46 +02:00
public ?string $privateKeyName = null;
2024-06-10 22:43:34 +02:00
2023-08-29 16:31:46 +02:00
public ?string $privateKeyDescription = null;
2024-06-10 22:43:34 +02:00
2023-08-29 16:31:46 +02:00
public ?PrivateKey $createdPrivateKey = null;
2023-08-30 11:06:44 +02:00
public ?Collection $servers = null;
2024-03-20 15:46:59 +01:00
2023-08-30 11:06:44 +02:00
public ?int $selectedExistingServer = null;
2024-06-10 22:43:34 +02:00
2023-08-29 16:31:46 +02:00
public ?string $remoteServerName = null;
2024-06-10 22:43:34 +02:00
2023-08-29 16:31:46 +02:00
public ?string $remoteServerDescription = null;
2024-06-10 22:43:34 +02:00
2023-08-29 16:31:46 +02:00
public ?string $remoteServerHost = null;
2024-06-10 22:43:34 +02:00
public ?int $remoteServerPort = 22;
2023-08-29 16:31:46 +02:00
public ?string $remoteServerUser = 'root';
2024-06-10 22:43:34 +02:00
2023-11-29 10:06:52 +01:00
public bool $isSwarmManager = false;
2024-06-10 22:43:34 +02:00
public bool $isCloudflareTunnel = false;
2024-06-10 22:43:34 +02:00
2023-08-29 16:31:46 +02:00
public ?Server $createdServer = null;
public Collection $projects;
2024-03-20 15:46:59 +01:00
public ?int $selectedProject = null;
2024-06-10 22:43:34 +02:00
2023-08-29 16:31:46 +02:00
public ?Project $createdProject = null;
2023-09-18 11:21:10 +02:00
public bool $dockerInstallationStarted = false;
2023-09-18 14:41:31 +02:00
public string $serverPublicKey;
2024-06-10 22:43:34 +02:00
2023-09-18 14:41:31 +02:00
public bool $serverReachable = true;
2023-08-29 16:31:46 +02:00
public function mount()
{
2024-05-21 14:29:06 +02:00
if (auth()->user()?->isMember() && auth()->user()->currentTeam()->show_boarding === true) {
return redirect()->route('dashboard');
}
2023-08-29 16:31:46 +02:00
$this->privateKeyName = generate_random_name();
$this->remoteServerName = generate_random_name();
if (isDev()) {
$this->privateKey = '-----BEGIN OPENSSH PRIVATE KEY-----
b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAAMwAAAAtzc2gtZW
QyNTUxOQAAACBbhpqHhqv6aI67Mj9abM3DVbmcfYhZAhC7ca4d9UCevAAAAJi/QySHv0Mk
hwAAAAtzc2gtZWQyNTUxOQAAACBbhpqHhqv6aI67Mj9abM3DVbmcfYhZAhC7ca4d9UCevA
AAAECBQw4jg1WRT2IGHMncCiZhURCts2s24HoDS0thHnnRKVuGmoeGq/pojrsyP1pszcNV
uZx9iFkCELtxrh31QJ68AAAAEXNhaWxANzZmZjY2ZDJlMmRkAQIDBA==
-----END OPENSSH PRIVATE KEY-----';
$this->privateKeyDescription = 'Created by Coolify';
$this->remoteServerDescription = 'Created by Coolify';
$this->remoteServerHost = 'coolify-testing-host';
}
// if ($this->currentState === 'create-project') {
// $this->getProjects();
// }
// if ($this->currentState === 'create-resource') {
// $this->selectExistingServer();
// $this->selectExistingProject();
// }
// if ($this->currentState === 'private-key') {
// $this->setServerType('remote');
// }
// if ($this->currentState === 'create-server') {
// $this->selectExistingPrivateKey();
// }
// if ($this->currentState === 'validate-server') {
// $this->selectExistingServer();
// }
// if ($this->currentState === 'select-existing-server') {
// $this->selectExistingServer();
// }
2024-03-20 15:46:59 +01:00
2023-08-29 16:31:46 +02:00
}
2024-06-10 22:43:34 +02:00
public function explanation()
{
2023-08-31 09:56:37 +02:00
if (isCloud()) {
2023-08-30 18:35:20 +02:00
return $this->setServerType('remote');
}
$this->currentState = 'select-server-type';
2023-08-30 18:35:20 +02:00
}
2023-09-14 10:39:05 +02:00
2023-08-29 16:31:46 +02:00
public function restartBoarding()
{
2024-03-13 12:11:37 +01:00
return redirect()->route('onboarding');
2023-08-29 16:31:46 +02:00
}
2024-06-10 22:43:34 +02:00
2023-08-29 16:31:46 +02:00
public function skipBoarding()
{
2023-09-08 18:33:26 +02:00
Team::find(currentTeam()->id)->update([
2024-06-10 22:43:34 +02:00
'show_boarding' => false,
2023-08-29 16:31:46 +02:00
]);
refreshSession();
2024-06-10 22:43:34 +02:00
2023-08-29 16:31:46 +02:00
return redirect()->route('dashboard');
}
2023-08-30 11:06:44 +02:00
public function setServerType(string $type)
2023-08-29 16:31:46 +02:00
{
$this->selectedServerType = $type;
if ($this->selectedServerType === 'localhost') {
2023-08-29 16:31:46 +02:00
$this->createdServer = Server::find(0);
2024-03-20 15:46:59 +01:00
$this->selectedExistingServer = 0;
2024-06-10 22:43:34 +02:00
if (! $this->createdServer) {
2023-12-07 19:06:32 +01:00
return $this->dispatch('error', 'Localhost server is not found. Something went wrong during installation. Please try to reinstall or contact support.');
2023-08-29 16:31:46 +02:00
}
2023-09-18 14:41:31 +02:00
$this->serverPublicKey = $this->createdServer->privateKey->publicKey();
2024-06-10 22:43:34 +02:00
2023-09-16 16:49:33 +02:00
return $this->validateServer('localhost');
} elseif ($this->selectedServerType === 'remote') {
if (isDev()) {
$this->privateKeys = PrivateKey::ownedByCurrentTeam(['name'])->get();
} else {
$this->privateKeys = PrivateKey::ownedByCurrentTeam(['name'])->where('id', '!=', 0)->get();
}
2023-08-30 11:06:44 +02:00
if ($this->privateKeys->count() > 0) {
$this->selectedExistingPrivateKey = $this->privateKeys->first()->id;
}
$this->servers = Server::ownedByCurrentTeam(['name'])->where('id', '!=', 0)->get();
if ($this->servers->count() > 0) {
$this->selectedExistingServer = $this->servers->first()->id;
$this->currentState = 'select-existing-server';
2024-06-10 22:43:34 +02:00
2023-08-30 11:06:44 +02:00
return;
}
$this->currentState = 'private-key';
2023-08-29 16:31:46 +02:00
}
}
2024-06-10 22:43:34 +02:00
2023-08-30 11:06:44 +02:00
public function selectExistingServer()
{
$this->createdServer = Server::find($this->selectedExistingServer);
2024-06-10 22:43:34 +02:00
if (! $this->createdServer) {
2023-12-07 19:06:32 +01:00
$this->dispatch('error', 'Server is not found.');
$this->currentState = 'private-key';
2024-06-10 22:43:34 +02:00
2023-08-30 11:06:44 +02:00
return;
}
$this->selectedExistingPrivateKey = $this->createdServer->privateKey->id;
2023-09-18 14:41:31 +02:00
$this->serverPublicKey = $this->createdServer->privateKey->publicKey();
$this->currentState = 'validate-server';
2023-08-30 11:06:44 +02:00
}
2024-06-10 22:43:34 +02:00
public function getProxyType()
{
2024-03-11 15:08:05 +01:00
// Set Default Proxy Type
$this->selectProxy(ProxyTypes::TRAEFIK->value);
// $proxyTypeSet = $this->createdServer->proxy->type;
// if (!$proxyTypeSet) {
// $this->currentState = 'select-proxy';
// return;
// }
2023-08-30 11:06:44 +02:00
$this->getProjects();
}
2024-06-10 22:43:34 +02:00
2023-08-29 20:34:01 +02:00
public function selectExistingPrivateKey()
{
2024-03-25 10:41:44 +01:00
if (is_null($this->selectedExistingPrivateKey)) {
$this->restartBoarding();
2024-06-10 22:43:34 +02:00
2024-03-25 10:41:44 +01:00
return;
}
2023-09-18 11:21:10 +02:00
$this->createdPrivateKey = PrivateKey::find($this->selectedExistingPrivateKey);
2023-09-28 13:46:53 +02:00
$this->privateKey = $this->createdPrivateKey->private_key;
$this->currentState = 'create-server';
2023-08-30 11:06:44 +02:00
}
2024-06-10 22:43:34 +02:00
2023-08-30 11:06:44 +02:00
public function createNewServer()
{
$this->selectedExistingServer = null;
$this->currentState = 'private-key';
2023-08-29 20:34:01 +02:00
}
2024-06-10 22:43:34 +02:00
2023-08-29 16:31:46 +02:00
public function setPrivateKey(string $type)
{
2023-08-30 11:06:44 +02:00
$this->selectedExistingPrivateKey = null;
2023-08-29 16:31:46 +02:00
$this->privateKeyType = $type;
if ($type === 'create') {
2023-08-29 16:31:46 +02:00
$this->createNewPrivateKey();
}
$this->currentState = 'create-private-key';
2023-08-29 16:31:46 +02:00
}
2024-06-10 22:43:34 +02:00
2023-08-29 16:31:46 +02:00
public function savePrivateKey()
{
$this->validate([
'privateKeyName' => 'required',
'privateKey' => 'required',
]);
2023-09-18 11:21:10 +02:00
$this->createdPrivateKey = PrivateKey::create([
'name' => $this->privateKeyName,
'description' => $this->privateKeyDescription,
'private_key' => $this->privateKey,
2024-06-10 22:43:34 +02:00
'team_id' => currentTeam()->id,
2023-09-18 11:21:10 +02:00
]);
$this->createdPrivateKey->save();
$this->currentState = 'create-server';
2023-08-29 16:31:46 +02:00
}
2024-06-10 22:43:34 +02:00
2023-08-29 16:31:46 +02:00
public function saveServer()
{
$this->validate([
'remoteServerName' => 'required',
'remoteServerHost' => 'required',
'remoteServerPort' => 'required|integer',
2023-08-29 16:31:46 +02:00
'remoteServerUser' => 'required',
]);
$this->privateKey = formatPrivateKey($this->privateKey);
$foundServer = Server::whereIp($this->remoteServerHost)->first();
if ($foundServer) {
2023-12-07 19:06:32 +01:00
return $this->dispatch('error', 'IP address is already in use by another team.');
}
2023-09-18 11:21:10 +02:00
$this->createdServer = Server::create([
'name' => $this->remoteServerName,
'ip' => $this->remoteServerHost,
'port' => $this->remoteServerPort,
'user' => $this->remoteServerUser,
'description' => $this->remoteServerDescription,
'private_key_id' => $this->createdPrivateKey->id,
'team_id' => currentTeam()->id,
]);
2023-11-29 10:06:52 +01:00
$this->createdServer->settings->is_swarm_manager = $this->isSwarmManager;
$this->createdServer->settings->is_cloudflare_tunnel = $this->isCloudflareTunnel;
2023-11-28 15:49:24 +01:00
$this->createdServer->settings->save();
2024-03-20 15:46:59 +01:00
$this->selectedExistingServer = $this->createdServer->id;
$this->currentState = 'validate-server';
2023-08-30 11:06:44 +02:00
}
2024-06-10 22:43:34 +02:00
public function installServer()
{
2024-03-05 16:23:46 +01:00
$this->dispatch('init', true);
}
2024-06-10 22:43:34 +02:00
public function validateServer()
{
2023-08-29 16:31:46 +02:00
try {
config()->set('coolify.mux_enabled', false);
2023-09-18 11:21:10 +02:00
// EC2 does not have `uptime` command, lol
2024-02-15 13:52:42 +01:00
instant_remote_process(['ls /'], $this->createdServer, true);
2023-09-18 11:21:10 +02:00
2023-09-18 14:41:31 +02:00
$this->createdServer->settings()->update([
2023-09-18 11:21:10 +02:00
'is_reachable' => true,
]);
} catch (\Throwable $e) {
2023-09-18 14:41:31 +02:00
$this->serverReachable = false;
$this->createdServer->delete();
2024-06-10 22:43:34 +02:00
2023-11-21 12:07:06 +01:00
return handleError(error: $e, livewire: $this);
}
2023-09-18 11:21:10 +02:00
try {
$dockerVersion = instant_remote_process(["docker version|head -2|grep -i version| awk '{print $2}'"], $this->createdServer, true);
$dockerVersion = checkMinimumDockerEngineVersion($dockerVersion);
if (is_null($dockerVersion)) {
$this->currentState = 'validate-server';
2023-11-21 12:07:06 +01:00
throw new \Exception('Docker not found or old version is installed.');
2023-09-16 16:49:33 +02:00
}
2023-09-18 14:41:31 +02:00
$this->createdServer->settings()->update([
'is_usable' => true,
]);
$this->getProxyType();
2023-09-11 17:36:30 +02:00
} catch (\Throwable $e) {
2023-11-21 12:07:06 +01:00
return handleError(error: $e, livewire: $this);
}
2023-09-18 11:21:10 +02:00
}
2024-06-10 22:43:34 +02:00
public function selectProxy(?string $proxyType = null)
2023-08-29 16:31:46 +02:00
{
2024-06-10 22:43:34 +02:00
if (! $proxyType) {
2023-08-30 11:06:44 +02:00
return $this->getProjects();
2023-08-29 16:31:46 +02:00
}
$this->createdServer->proxy->type = $proxyType;
$this->createdServer->proxy->status = 'exited';
$this->createdServer->save();
2023-08-30 11:06:44 +02:00
$this->getProjects();
}
public function getProjects()
{
2023-08-30 11:06:44 +02:00
$this->projects = Project::ownedByCurrentTeam(['name'])->get();
if ($this->projects->count() > 0) {
2024-03-20 15:46:59 +01:00
$this->selectedProject = $this->projects->first()->id;
2023-08-30 11:06:44 +02:00
}
$this->currentState = 'create-project';
2023-08-29 16:31:46 +02:00
}
2024-06-10 22:43:34 +02:00
public function selectExistingProject()
{
2024-03-20 15:46:59 +01:00
$this->createdProject = Project::find($this->selectedProject);
$this->currentState = 'create-resource';
2023-08-30 11:06:44 +02:00
}
2024-06-10 22:43:34 +02:00
2023-08-29 16:31:46 +02:00
public function createNewProject()
{
$this->createdProject = Project::create([
2024-06-10 22:43:34 +02:00
'name' => 'My first project',
'team_id' => currentTeam()->id,
2023-08-29 16:31:46 +02:00
]);
$this->currentState = 'create-resource';
2023-08-29 16:31:46 +02:00
}
2024-06-10 22:43:34 +02:00
2023-08-29 16:31:46 +02:00
public function showNewResource()
{
$this->skipBoarding();
2024-06-10 22:43:34 +02:00
2023-08-29 16:31:46 +02:00
return redirect()->route(
2024-01-07 16:23:41 +01:00
'project.resource.create',
2023-08-29 16:31:46 +02:00
[
'project_uuid' => $this->createdProject->uuid,
'environment_name' => 'production',
'server' => $this->createdServer->id,
2023-08-29 16:31:46 +02:00
]
);
}
2024-06-10 22:43:34 +02:00
2023-08-29 16:31:46 +02:00
private function createNewPrivateKey()
{
$this->privateKeyName = generate_random_name();
$this->privateKeyDescription = 'Created by Coolify';
2023-08-29 20:34:01 +02:00
['private' => $this->privateKey, 'public' => $this->publicKey] = generateSSHKey();
2023-08-29 16:31:46 +02:00
}
2024-06-10 22:43:34 +02:00
2023-08-29 16:31:46 +02:00
public function render()
{
return view('livewire.boarding.index')->layout('layouts.boarding');
}
}