fix: boarding

fix: error handling
fix: restarting state
This commit is contained in:
Andras Bacsai
2023-09-15 15:34:25 +02:00
parent fcf7c5ddd5
commit da4c2ee60f
71 changed files with 326 additions and 290 deletions

View File

@@ -5,6 +5,7 @@ namespace App\Actions\CoolifyTask;
use App\Enums\ActivityTypes;
use App\Enums\ProcessStatus;
use App\Jobs\ApplicationDeploymentJob;
use App\Models\Server;
use Illuminate\Process\ProcessResult;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Process;
@@ -94,7 +95,7 @@ class RunRemoteProcess
]);
$this->activity->save();
if ($processResult->exitCode() != 0 && !$this->ignore_errors) {
throw new \RuntimeException($processResult->errorOutput());
throw new \RuntimeException($processResult->errorOutput(), $processResult->exitCode());
}
return $processResult;
@@ -102,12 +103,11 @@ class RunRemoteProcess
protected function getCommand(): string
{
$user = $this->activity->getExtraProperty('user');
$server_ip = $this->activity->getExtraProperty('server_ip');
$port = $this->activity->getExtraProperty('port');
$server_uuid = $this->activity->getExtraProperty('server_uuid');
$command = $this->activity->getExtraProperty('command');
$server = Server::whereUuid($server_uuid)->firstOrFail();
return generateSshCommand($server_ip, $user, $port, $command);
return generateSshCommand($server, $command);
}
protected function handleOutput(string $type, string $output)

View File

@@ -27,6 +27,10 @@ class StartProxy
$server->proxy->last_applied_settings = Str::of($docker_compose_yml_base64)->pipe('md5')->value;
$server->save();
$commands = [
"command -v lsof >/dev/null || echo '####### Installing lsof...'",
"command -v lsof >/dev/null || apt-get update",
"command -v lsof >/dev/null || apt install -y lsof",
"command -v lsof >/dev/null || command -v fuser >/dev/null || apt install -y psmisc",
"echo '####### Creating required Docker networks...'",
...$create_networks_command,
"cd $proxy_path",
@@ -35,8 +39,11 @@ class StartProxy
'docker compose pull',
"echo '####### Stopping existing coolify-proxy...'",
'docker compose down -v --remove-orphans',
"lsof -nt -i:80 | xargs -r kill -9",
"lsof -nt -i:443 | xargs -r kill -9",
"command -v lsof >/dev/null && lsof -nt -i:80 | xargs -r kill -9",
"command -v lsof >/dev/null && lsof -nt -i:443 | xargs -r kill -9",
"command -v fuser >/dev/null && fuser -k 80/tcp",
"command -v fuser >/dev/null && fuser -k 443/tcp",
"command -v fuser >/dev/null || command -v lsof >/dev/null || echo '####### Could not kill existing processes listening on port 80 & 443. Please stop the process holding these ports...'",
"systemctl disable nginx > /dev/null 2>&1 || true",
"systemctl disable apache2 > /dev/null 2>&1 || true",
"systemctl disable apache > /dev/null 2>&1 || true",

View File

@@ -12,10 +12,8 @@ use Spatie\LaravelData\Data;
class CoolifyTaskArgs extends Data
{
public function __construct(
public string $server_ip,
public string $server_uuid,
public string $command,
public int $port,
public string $user,
public string $type,
public ?string $type_uuid = null,
public ?Model $model = null,

View File

@@ -45,8 +45,11 @@ class Handler extends ExceptionHandler
public function register(): void
{
$this->reportable(function (Throwable $e) {
if (isDev()) {
return;
}
$this->settings = InstanceSettings::get();
if ($this->settings->do_not_track || isDev()) {
if ($this->settings->do_not_track) {
return;
}
app('sentry')->configureScope(

View File

@@ -14,7 +14,6 @@ use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Crypt;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Str;
use Throwable;
class Controller extends BaseController
{
@@ -153,7 +152,7 @@ class Controller extends BaseController
} else {
abort(401);
}
} catch (Throwable $e) {
} catch (\Throwable $e) {
ray($e->getMessage());
throw $e;
}
@@ -172,7 +171,7 @@ class Controller extends BaseController
}
$invitation->delete();
return redirect()->route('team.index');
} catch (Throwable $e) {
} catch (\Throwable $e) {
throw $e;
}
}

View File

@@ -9,6 +9,7 @@ use App\Models\Server;
use App\Models\Team;
use Illuminate\Support\Collection;
use Livewire\Component;
use Visus\Cuid2\Cuid2;
class Index extends Component
{
@@ -53,7 +54,8 @@ uZx9iFkCELtxrh31QJ68AAAAEXNhaWxANzZmZjY2ZDJlMmRkAQIDBA==
$this->remoteServerHost = 'coolify-testing-host';
}
}
public function explanation() {
public function explanation()
{
if (isCloud()) {
return $this->setServerType('remote');
}
@@ -115,7 +117,8 @@ uZx9iFkCELtxrh31QJ68AAAAEXNhaWxANzZmZjY2ZDJlMmRkAQIDBA==
$this->getProxyType();
$this->getProjects();
}
public function getProxyType() {
public function getProxyType()
{
$proxyTypeSet = $this->createdServer->proxy->type;
if (!$proxyTypeSet) {
$this->currentState = 'select-proxy';
@@ -153,49 +156,68 @@ uZx9iFkCELtxrh31QJ68AAAAEXNhaWxANzZmZjY2ZDJlMmRkAQIDBA==
{
$this->validate([
'remoteServerName' => 'required',
'remoteServerHost' => 'required',
'remoteServerPort' => 'required',
'remoteServerHost' => 'required|ip',
'remoteServerPort' => 'required|integer',
'remoteServerUser' => 'required',
]);
$this->privateKey = formatPrivateKey($this->privateKey);
$this->createdPrivateKey = PrivateKey::create([
'name' => $this->privateKeyName,
'description' => $this->privateKeyDescription,
'private_key' => $this->privateKey,
'team_id' => currentTeam()->id
]);
$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
]);
$this->createdPrivateKey = new PrivateKey();
$this->createdPrivateKey->private_key = $this->privateKey;
$this->createdPrivateKey->name = $this->privateKeyName;
$this->createdPrivateKey->description = $this->privateKeyDescription;
$this->createdPrivateKey->team_id = currentTeam()->id;
$foundServer = Server::whereIp($this->remoteServerHost)->first();
if ($foundServer) {
return $this->emit('error', 'IP address is already in use by another team.');
}
$this->createdServer = new Server();
$this->createdServer->uuid = (string)new Cuid2(7);
$this->createdServer->name = $this->remoteServerName;
$this->createdServer->ip = $this->remoteServerHost;
$this->createdServer->port = $this->remoteServerPort;
$this->createdServer->user = $this->remoteServerUser;
$this->createdServer->description = $this->remoteServerDescription;
$this->createdServer->privateKey = $this->createdPrivateKey;
$this->createdServer->team_id = currentTeam()->id;
ray($this->createdServer);
$this->validateServer();
}
public function validateServer() {
public function validateServer()
{
try {
['uptime' => $uptime, 'dockerVersion' => $dockerVersion] = validateServer($this->createdServer);
if (!$uptime) {
throw new \Exception('Server is not reachable.');
} else {
$this->createdServer->settings->update([
'is_reachable' => true,
]);
$this->emit('success', 'Server is reachable.');
}
ray($dockerVersion, $uptime);
if (!$dockerVersion) {
$this->emit('error', 'Docker is not installed on the server.');
$this->currentState = 'install-docker';
return;
$customErrorMessage = "Server is not reachable:";
config()->set('coolify.mux_enabled', false);
instant_remote_process(['uptime'], $this->createdServer, true);
$dockerVersion = instant_remote_process(["docker version|head -2|grep -i version| awk '{print $2}'"], $this->createdServer, true);
$dockerVersion = checkMinimumDockerEngineVersion($dockerVersion);
if (is_null($dockerVersion)) {
throw new \Exception('No Docker Engine or older than 23 version installed.');
}
$customErrorMessage = "Cannot create Server or Private Key. Please try again.";
$createdPrivateKey = PrivateKey::create([
'name' => $this->privateKeyName,
'description' => $this->privateKeyDescription,
'private_key' => $this->privateKey,
'team_id' => currentTeam()->id
]);
$server = Server::create([
'name' => $this->remoteServerName,
'ip' => $this->remoteServerHost,
'port' => $this->remoteServerPort,
'user' => $this->remoteServerUser,
'description' => $this->remoteServerDescription,
'private_key_id' => $createdPrivateKey->id,
'team_id' => currentTeam()->id,
]);
$server->settings->is_reachable = true;
$server->settings->is_usable = true;
$server->settings->save();
$this->getProxyType();
} catch (\Throwable $e) {
return general_error_handler(customErrorMessage: "Server is not reachable. Reason: {$e->getMessage()}", that: $this);
return handleError(error: $e, customErrorMessage: $customErrorMessage, livewire: $this);
}
}
public function installDocker()
@@ -215,14 +237,16 @@ uZx9iFkCELtxrh31QJ68AAAAEXNhaWxANzZmZjY2ZDJlMmRkAQIDBA==
$this->getProjects();
}
public function getProjects() {
public function getProjects()
{
$this->projects = Project::ownedByCurrentTeam(['name'])->get();
if ($this->projects->count() > 0) {
$this->selectedExistingProject = $this->projects->first()->id;
}
$this->currentState = 'create-project';
}
public function selectExistingProject() {
public function selectExistingProject()
{
$this->createdProject = Project::find($this->selectedExistingProject);
$this->currentState = 'create-resource';
}
@@ -242,7 +266,7 @@ uZx9iFkCELtxrh31QJ68AAAAEXNhaWxANzZmZjY2ZDJlMmRkAQIDBA==
[
'project_uuid' => $this->createdProject->uuid,
'environment_name' => 'production',
'server'=> $this->createdServer->id,
'server' => $this->createdServer->id,
]
);
}

View File

@@ -38,7 +38,7 @@ class Form extends Component
$this->destination->delete();
return redirect()->route('dashboard');
} catch (\Throwable $e) {
return general_error_handler(err: $e);
return handleError($e);
}
}
}

View File

@@ -72,7 +72,7 @@ class StandaloneDocker extends Component
$this->createNetworkAndAttachToProxy();
return redirect()->route('destination.show', $docker->uuid);
} catch (\Throwable $e) {
return general_error_handler(err: $e, that: $this);
return handleError($e, $this);
}
}

View File

@@ -37,7 +37,7 @@ class ForcePasswordReset extends Component
}
return redirect()->route('dashboard');
} catch (\Throwable $e) {
return general_error_handler(err: $e, that: $this);
return handleError($e, $this);
}
}
}

View File

@@ -44,7 +44,7 @@ class Help extends Component
send_user_an_email($mail, auth()->user()?->email, 'hi@coollabs.io');
$this->emit('success', 'Your message has been sent successfully. We will get in touch with you as soon as possible.');
} catch (\Throwable $e) {
return general_error_handler($e, $this);
return handleError($e, $this);
}
}
public function render()

View File

@@ -64,7 +64,7 @@ class EmailSettings extends Component
$this->team->save();
$this->emit('success', 'Settings saved successfully.');
} catch (\Throwable $e) {
return general_error_handler($e, $this);
return handleError($e, $this);
}
}
public function sendTestNotification()
@@ -83,7 +83,7 @@ class EmailSettings extends Component
$this->team->save();
$this->emit('success', 'Settings saved successfully.');
} catch (\Throwable $e) {
return general_error_handler($e, $this);
return handleError($e, $this);
}
}
@@ -94,7 +94,7 @@ class EmailSettings extends Component
$this->submitResend();
} catch (\Throwable $e) {
$this->team->smtp_enabled = false;
return general_error_handler($e, $this);
return handleError($e, $this);
}
}
public function instantSave()
@@ -104,7 +104,7 @@ class EmailSettings extends Component
$this->submit();
} catch (\Throwable $e) {
$this->team->smtp_enabled = false;
return general_error_handler($e, $this);
return handleError($e, $this);
}
}
public function saveModel()
@@ -130,7 +130,7 @@ class EmailSettings extends Component
$this->emit('success', 'Settings saved successfully.');
} catch (\Throwable $e) {
$this->team->smtp_enabled = false;
return general_error_handler($e, $this);
return handleError($e, $this);
}
}
public function submitResend()
@@ -146,7 +146,7 @@ class EmailSettings extends Component
$this->emit('success', 'Settings saved successfully.');
} catch (\Throwable $e) {
$this->team->resend_enabled = false;
return general_error_handler($e, $this);
return handleError($e, $this);
}
}
public function copyFromInstanceSettings()

View File

@@ -25,8 +25,8 @@ class Change extends Component
{
try {
$this->public_key = $this->private_key->publicKey();
}catch(\Exception $e) {
return general_error_handler(err: $e, that: $this);
}catch(\Throwable $e) {
return handleError($e, $this);
}
}
public function delete()
@@ -39,7 +39,7 @@ class Change extends Component
}
$this->emit('error', 'This private key is in use and cannot be deleted. Please delete all servers, applications, and GitHub/GitLab apps that use this private key before deleting it.');
} catch (\Throwable $e) {
return general_error_handler(err: $e, that: $this);
return handleError($e, $this);
}
}
@@ -50,7 +50,7 @@ class Change extends Component
$this->private_key->save();
refresh_server_connection($this->private_key);
} catch (\Throwable $e) {
return general_error_handler(err: $e, that: $this);
return handleError($e, $this);
}
}
}

View File

@@ -58,7 +58,7 @@ class Create extends Component
}
return redirect()->route('security.private-key.show', ['private_key_uuid' => $private_key->uuid]);
} catch (\Throwable $e) {
return general_error_handler(err: $e, that: $this);
return handleError($e, $this);
}
}
}

View File

@@ -34,7 +34,7 @@ class Form extends Component
'name' => $this->name,
]);
} catch (\Throwable $e) {
return general_error_handler(err: $e, that: $this);
return handleError($e, $this);
}
}
}

View File

@@ -29,7 +29,7 @@ class AddEmpty extends Component
]);
return redirect()->route('project.show', $project->uuid);
} catch (\Throwable $e) {
general_error_handler($e, $this);
return handleError($e, $this);
} finally {
$this->name = '';
}

View File

@@ -32,7 +32,7 @@ class AddEnvironment extends Component
'environment_name' => $environment->name,
]);
} catch (\Throwable $e) {
general_error_handler($e, $this);
handleError($e, $this);
} finally {
$this->name = '';
}

View File

@@ -65,7 +65,7 @@ class DeploymentNavbar extends Component
]);
}
} catch (\Throwable $e) {
return general_error_handler(err: $e, that: $this);
return handleError($e, $this);
}
}
}

View File

@@ -160,7 +160,7 @@ class General extends Component
$this->application->save();
$this->emit('success', 'Application settings updated!');
} catch (\Throwable $e) {
return general_error_handler(err: $e, that: $this);
return handleError($e, $this);
}
}
}

View File

@@ -30,7 +30,7 @@ class Previews extends Component
$this->pull_requests = $data->sortBy('number')->values();
} catch (\Throwable $e) {
$this->rate_limit_remaining = 0;
return general_error_handler(err: $e, that: $this);
return handleError($e, $this);
}
}
@@ -59,7 +59,7 @@ class Previews extends Component
'environment_name' => $this->parameters['environment_name'],
]);
} catch (\Throwable $e) {
return general_error_handler(err: $e, that: $this);
return handleError($e, $this);
}
}
@@ -79,7 +79,7 @@ class Previews extends Component
ApplicationPreview::where('application_id', $this->application->id)->where('pull_request_id', $pull_request_id)->delete();
$this->application->refresh();
} catch (\Throwable $e) {
return general_error_handler(err: $e, that: $this);
return handleError($e, $this);
}
}

View File

@@ -65,7 +65,7 @@ class Rollback extends Component
];
})->toArray();
} catch (\Throwable $e) {
return general_error_handler(err: $e, that: $this);
return handleError($e, $this);
}
}
}

View File

@@ -43,7 +43,7 @@ class CreateScheduledBackup extends Component
]);
$this->emit('refreshScheduledBackups');
} catch (\Throwable $e) {
general_error_handler($e, $this);
handleError($e, $this);
} finally {
$this->frequency = '';
$this->save_s3 = true;

View File

@@ -35,7 +35,7 @@ class Heading extends Component
public function stop()
{
remote_process(
instant_remote_process(
["docker rm -f {$this->database->uuid}"],
$this->database->destination->server
);
@@ -45,7 +45,7 @@ class Heading extends Component
}
$this->database->status = 'stopped';
$this->database->save();
$this->emit('refresh');
$this->check_status();
// $this->database->environment->project->team->notify(new StatusChanged($this->database));
}

View File

@@ -36,7 +36,7 @@ class InitScript extends Component
$this->script['filename'] = $this->filename;
$this->emitUp('save_init_script', $this->script);
} catch (Exception $e) {
return general_error_handler(err: $e, that: $this);
return handleError($e, $this);
}
}

View File

@@ -5,6 +5,7 @@ namespace App\Http\Livewire\Project\Database\Postgresql;
use App\Models\StandalonePostgresql;
use Exception;
use Livewire\Component;
use function Aws\filter;
class General extends Component
@@ -73,9 +74,9 @@ class General extends Component
}
$this->getDbUrl();
$this->database->save();
} catch(Exception $e) {
} catch(\Throwable $e) {
$this->database->is_public = !$this->database->is_public;
return general_error_handler(err: $e, that: $this);
return handleError($e, $this);
}
}
@@ -140,7 +141,7 @@ class General extends Component
$this->database->save();
$this->emit('success', 'Database updated successfully.');
} catch (Exception $e) {
return general_error_handler(err: $e, that: $this);
return handleError($e, $this);
}
}
}

View File

@@ -20,7 +20,7 @@ class Edit extends Component
$this->project->save();
$this->emit('saved');
} catch (\Throwable $e) {
return general_error_handler($e, $this);
return handleError($e, $this);
}
}
}

View File

@@ -165,7 +165,7 @@ class GithubPrivateRepository extends Component
'project_uuid' => $project->uuid,
]);
} catch (\Throwable $e) {
return general_error_handler(err: $e, that: $this);
return handleError($e, $this);
}
}

View File

@@ -118,7 +118,7 @@ class GithubPrivateRepositoryDeployKey extends Component
'application_uuid' => $application->uuid,
]);
} catch (\Throwable $e) {
return general_error_handler(err: $e, that: $this);
return handleError($e, $this);
}
}

View File

@@ -76,14 +76,14 @@ class PublicGitRepository extends Component
$this->get_branch();
$this->selected_branch = $this->git_branch;
} catch (\Throwable $e) {
return general_error_handler(err: $e, that: $this);
return handleError($e, $this);
}
if (!$this->branch_found && $this->git_branch == 'main') {
try {
$this->git_branch = 'master';
$this->get_branch();
} catch (\Throwable $e) {
return general_error_handler(err: $e, that: $this);
return handleError($e, $this);
}
}
}
@@ -162,7 +162,7 @@ class PublicGitRepository extends Component
'application_uuid' => $application->uuid,
]);
} catch (\Throwable $e) {
return general_error_handler(err: $e, that: $this);
return handleError($e, $this);
}
}
}

View File

@@ -41,7 +41,7 @@ class Select extends Component
// instantCommand("psql {$this->existingPostgresqlUrl} -c 'SELECT 1'");
// $this->emit('success', 'Successfully connected to the database.');
// } catch (\Throwable $e) {
// return general_error_handler($e, $this);
// return handleError($e, $this);
// }
// }
public function setType(string $type)

View File

@@ -114,7 +114,7 @@ class All extends Component
$this->refreshEnvs();
$this->emit('success', 'Environment variable added successfully.');
} catch (\Throwable $e) {
return general_error_handler(err: $e, that: $this);
return handleError($e, $this);
}
}
}

View File

@@ -54,7 +54,7 @@ class ResourceLimits extends Component
$this->resource->save();
$this->emit('success', 'Resource limits updated successfully.');
} catch (\Throwable $e) {
return general_error_handler(err: $e, that: $this);
return handleError($e, $this);
}
}
}

View File

@@ -29,7 +29,7 @@ class All extends Component
$this->emit('success', 'Storage added successfully');
$this->emit('clearAddStorage');
} catch (\Throwable $e) {
return general_error_handler(err: $e, that: $this);
return handleError($e, $this);
}
}
}

View File

@@ -33,7 +33,7 @@ class RunCommand extends Component
$activity = remote_process([$this->command], Server::where('uuid', $this->server)->first(), ignore_errors: true);
$this->emit('newMonitorActivity', $activity->id);
} catch (\Throwable $e) {
return general_error_handler(err: $e);
return handleError($e, $this);
}
}
}

View File

@@ -51,12 +51,12 @@ class Form extends Component
public function validateServer()
{
try {
['uptime' => $uptime, 'dockerVersion' => $dockerVersion] = validateServer($this->server);
['uptime' => $uptime, 'dockerVersion' => $dockerVersion] = validateServer($this->server, true);
if ($uptime) {
$this->uptime = $uptime;
$this->emit('success', 'Server is reachable!');
$this->emit('success', 'Server is reachable.');
} else {
$this->emit('error', 'Server is not reachable');
$this->emit('error', 'Server is not reachable.');
return;
}
if ($dockerVersion) {
@@ -64,10 +64,10 @@ class Form extends Component
$this->emit('proxyStatusUpdated');
$this->emit('success', 'Docker Engine 23+ is installed!');
} else {
$this->emit('error', 'Old (lower than 23) or no Docker version detected. Install Docker Engine on the General tab.');
$this->emit('error', 'No Docker Engine or older than 23 version installed.');
}
} catch (\Throwable $e) {
return general_error_handler($e, that: $this);
return handleError($e, $this, customErrorMessage: "Server is not reachable: ");
}
}
@@ -82,7 +82,7 @@ class Form extends Component
$this->server->delete();
return redirect()->route('server.all');
} catch (\Throwable $e) {
return general_error_handler(err: $e, that: $this);
return handleError($e, $this);
}
}
public function submit()

View File

@@ -79,7 +79,7 @@ class ByIp extends Component
$server->settings->save();
return redirect()->route('server.show', $server->uuid);
} catch (\Throwable $e) {
return general_error_handler(err: $e);
return handleError($e);
}
}
}

View File

@@ -56,7 +56,7 @@ class Proxy extends Component
setup_default_redirect_404(redirect_url: $this->server->proxy->redirect_url, server: $this->server);
$this->emit('success', 'Proxy configuration saved.');
} catch (\Throwable $e) {
return general_error_handler(err: $e);
return handleError($e);
}
}
@@ -65,7 +65,7 @@ class Proxy extends Component
try {
$this->proxy_settings = resolve(CheckConfigurationSync::class)($this->server, true);
} catch (\Throwable $e) {
return general_error_handler(err: $e);
return handleError($e);
}
}
@@ -75,7 +75,7 @@ class Proxy extends Component
ray('loadProxyConfiguration');
$this->proxy_settings = resolve(CheckConfigurationSync::class)($this->server);
} catch (\Throwable $e) {
return general_error_handler(err: $e);
return handleError($e);
}
}
}

View File

@@ -24,7 +24,7 @@ class Status extends Component
$this->emit('proxyStatusUpdated');
}
} catch (\Throwable $e) {
return general_error_handler(err: $e);
return handleError($e);
}
}
public function getProxyStatusWithNoti()

View File

@@ -18,7 +18,7 @@ class Show extends Component
return redirect()->route('server.all');
}
} catch (\Throwable $e) {
return general_error_handler(err: $e, that: $this);
return handleError($e, $this);
}
}
public function render()

View File

@@ -28,14 +28,14 @@ class ShowPrivateKey extends Component
]);
$this->server->refresh();
refresh_server_connection($this->server->privateKey);
return general_error_handler($e, that: $this);
return handleError($e, $this);
}
}
public function checkConnection()
{
try {
['uptime' => $uptime, 'dockerVersion' => $dockerVersion] = validateServer($this->server);
['uptime' => $uptime, 'dockerVersion' => $dockerVersion] = validateServer($this->server, true);
if ($uptime) {
$this->emit('success', 'Server is reachable with this private key.');
} else {
@@ -48,7 +48,7 @@ class ShowPrivateKey extends Component
$this->emit('error', 'Old (lower than 23) or no Docker version detected. Install Docker Engine on the General tab.');
}
} catch (\Throwable $e) {
throw new \Exception($e->getMessage());
return handleError($e, $this);
}
}

View File

@@ -51,7 +51,7 @@ class Email extends Component
$this->settings->save();
$this->emit('success', 'Settings saved successfully.');
} catch (\Throwable $e) {
return general_error_handler($e, $this);
return handleError($e, $this);
}
}
public function submitResend() {
@@ -64,7 +64,7 @@ class Email extends Component
$this->emit('success', 'Settings saved successfully.');
} catch (\Throwable $e) {
$this->settings->resend_enabled = false;
return general_error_handler($e, $this);
return handleError($e, $this);
}
}
public function instantSaveResend() {
@@ -72,7 +72,7 @@ class Email extends Component
$this->settings->smtp_enabled = false;
$this->submitResend();
} catch (\Throwable $e) {
return general_error_handler($e, $this);
return handleError($e, $this);
}
}
public function instantSave()
@@ -81,7 +81,7 @@ class Email extends Component
$this->settings->resend_enabled = false;
$this->submit();
} catch (\Throwable $e) {
return general_error_handler($e, $this);
return handleError($e, $this);
}
}
@@ -100,7 +100,7 @@ class Email extends Component
$this->settings->save();
$this->emit('success', 'Settings saved successfully.');
} catch (\Throwable $e) {
return general_error_handler($e, $this);
return handleError($e, $this);
}
}

View File

@@ -52,7 +52,7 @@ class Change extends Component
$this->validate();
$this->github_app->save();
} catch (\Throwable $e) {
return general_error_handler(err: $e, that: $this);
return handleError($e, $this);
}
}
@@ -66,7 +66,7 @@ class Change extends Component
$this->github_app->delete();
redirect()->route('source.all');
} catch (\Throwable $e) {
return general_error_handler(err: $e, that: $this);
return handleError($e, $this);
}
}
}

View File

@@ -50,7 +50,7 @@ class Create extends Component
}
redirect()->route('source.github.show', ['github_app_uuid' => $github_app->uuid]);
} catch (\Throwable $e) {
return general_error_handler(err: $e, that: $this);
return handleError($e, $this);
}
}
}

View File

@@ -31,7 +31,7 @@ class Actions extends Component
$this->emit('reloadWindow', 5000);
}
} catch (\Throwable $e) {
return general_error_handler($e, $this);
return handleError($e, $this);
}
}
public function resume()
@@ -66,7 +66,7 @@ class Actions extends Component
$this->emit('reloadWindow', 5000);
}
} catch (\Throwable $e) {
return general_error_handler($e, $this);
return handleError($e, $this);
}
}
public function stripeCustomerPortal() {

View File

@@ -32,7 +32,7 @@ class Create extends Component
refreshSession();
return redirect()->route('team.index');
} catch (\Throwable $e) {
return general_error_handler($e, $this);
return handleError($e, $this);
}
}
}

View File

@@ -28,7 +28,7 @@ class Form extends Component
try {
$this->team->save();
} catch (\Throwable $e) {
return general_error_handler($e, $this);
return handleError($e, $this);
}
}
}

View File

@@ -36,7 +36,7 @@ class InviteLink extends Component
try {
$member_emails = currentTeam()->members()->get()->pluck('email');
if ($member_emails->contains($this->email)) {
return general_error_handler(that: $this, customErrorMessage: "$this->email is already a member of " . currentTeam()->name . ".");
return handleError(livewire: $this, customErrorMessage: "$this->email is already a member of " . currentTeam()->name . ".");
}
$uuid = new Cuid2(32);
$link = url('/') . config('constants.invitation.link.base_url') . $uuid;
@@ -57,7 +57,7 @@ class InviteLink extends Component
if (!is_null($invitation)) {
$invitationValid = $invitation->isValid();
if ($invitationValid) {
return general_error_handler(that: $this, customErrorMessage: "Pending invitation already exists for $this->email.");
return handleError(livewire: $this, customErrorMessage: "Pending invitation already exists for $this->email.");
} else {
$invitation->delete();
}
@@ -91,7 +91,7 @@ class InviteLink extends Component
if ($e->getCode() === '23505') {
$error_message = 'Invitation already sent.';
}
return general_error_handler(err: $e, that: $this, customErrorMessage: $error_message);
return handleError(error: $e, livewire: $this, customErrorMessage: $error_message);
}
}
}

View File

@@ -68,7 +68,7 @@ class Create extends Component
$this->storage->save();
return redirect()->route('team.storages.show', $this->storage->uuid);
} catch (\Throwable $e) {
return general_error_handler($e, $this);
return handleError($e, $this);
}
}
@@ -78,7 +78,7 @@ class Create extends Component
$this->storage->testConnection();
return $this->emit('success', 'Connection is working. Tested with "ListObjectsV2" action.');
} catch (\Throwable $e) {
return general_error_handler($e, $this);
return handleError($e, $this);
}
}
}

View File

@@ -33,7 +33,7 @@ class Form extends Component
$this->storage->testConnection();
return $this->emit('success', 'Connection is working. Tested with "ListObjectsV2" action.');
} catch (\Throwable $e) {
return general_error_handler($e, $this);
return handleError($e, $this);
}
}
@@ -43,7 +43,7 @@ class Form extends Component
$this->storage->delete();
return redirect()->route('team.storages.all');
} catch (\Throwable $e) {
return general_error_handler($e, $this);
return handleError($e, $this);
}
}
@@ -56,7 +56,7 @@ class Form extends Component
$this->storage->save();
$this->emit('success', 'Storage settings saved.');
} catch (\Throwable $e) {
return general_error_handler($e, $this);
return handleError($e, $this);
}
}
}

View File

@@ -38,7 +38,7 @@ class Upgrade extends Component
resolve(UpdateCoolify::class)(true);
Toaster::success("Upgrading to {$this->latestVersion} version...");
} catch (\Throwable $e) {
return general_error_handler(err: $e, that: $this);
return handleError($e, $this);
}
}
}

View File

@@ -54,7 +54,7 @@ class Index extends Component
$this->emit('success', 'Check your email to verify your email address.');
dispatch(new SendConfirmationForWaitlistJob($this->email, $waitlist->uuid));
} catch (\Throwable $e) {
return general_error_handler(err: $e, that: $this);
return handleError($e, $this);
}
}
}

View File

@@ -177,7 +177,7 @@ class ApplicationDeploymentJob implements ShouldQueue, ShouldBeEncrypted
$this->prepare_builder_image();
$this->execute_remote_command(
[
$this->execute_in_builder("echo '$dockerfile_base64' | base64 -d > $this->workdir/Dockerfile")
executeInDocker($this->deployment_uuid, "echo '$dockerfile_base64' | base64 -d > $this->workdir/Dockerfile")
],
);
$this->build_image_name = Str::lower("{$this->application->git_repository}:build");
@@ -302,7 +302,7 @@ class ApplicationDeploymentJob implements ShouldQueue, ShouldBeEncrypted
$this->stop_running_container();
$this->execute_remote_command(
["echo -n 'Starting preview deployment.'"],
[$this->execute_in_builder("docker compose --project-directory {$this->workdir} up -d >/dev/null"), "hidden" => true],
[executeInDocker($this->deployment_uuid, "docker compose --project-directory {$this->workdir} up -d >/dev/null"), "hidden" => true],
);
}
@@ -324,16 +324,12 @@ class ApplicationDeploymentJob implements ShouldQueue, ShouldBeEncrypted
"hidden" => true,
],
[
"command" => $this->execute_in_builder("mkdir -p {$this->workdir}")
"command" => executeInDocker($this->deployment_uuid, "mkdir -p {$this->workdir}")
],
);
}
private function execute_in_builder(string $command)
{
return "docker exec {$this->deployment_uuid} bash -c '{$command}'";
// return "docker exec {$this->deployment_uuid} bash -c '{$command} |& tee -a /proc/1/fd/1; [ \$PIPESTATUS -eq 0 ] || exit \$PIPESTATUS'";
}
private function clone_repository()
{
@@ -345,7 +341,7 @@ class ApplicationDeploymentJob implements ShouldQueue, ShouldBeEncrypted
$this->importing_git_repository()
],
[
$this->execute_in_builder("cd {$this->workdir} && git rev-parse HEAD"),
executeInDocker($this->deployment_uuid, "cd {$this->workdir} && git rev-parse HEAD"),
"hidden" => true,
"save" => "git_commit_sha"
],
@@ -372,13 +368,13 @@ class ApplicationDeploymentJob implements ShouldQueue, ShouldBeEncrypted
$git_clone_command = "{$git_clone_command} {$this->source->html_url}/{$this->application->git_repository} {$this->workdir}";
$git_clone_command = $this->set_git_import_settings($git_clone_command);
$commands->push($this->execute_in_builder($git_clone_command));
$commands->push(executeInDocker($this->deployment_uuid, $git_clone_command));
} else {
$github_access_token = generate_github_installation_token($this->source);
$commands->push($this->execute_in_builder("git clone -q -b {$this->application->git_branch} $source_html_url_scheme://x-access-token:$github_access_token@$source_html_url_host/{$this->application->git_repository}.git {$this->workdir}"));
$commands->push(executeInDocker($this->deployment_uuid, "git clone -q -b {$this->application->git_branch} $source_html_url_scheme://x-access-token:$github_access_token@$source_html_url_host/{$this->application->git_repository}.git {$this->workdir}"));
}
if ($this->pull_request_id !== 0) {
$commands->push($this->execute_in_builder("cd {$this->workdir} && git fetch origin pull/{$this->pull_request_id}/head:$pr_branch_name && git checkout $pr_branch_name"));
$commands->push(executeInDocker($this->deployment_uuid, "cd {$this->workdir} && git fetch origin pull/{$this->pull_request_id}/head:$pr_branch_name && git checkout $pr_branch_name"));
}
return $commands->implode(' && ');
}
@@ -388,10 +384,10 @@ class ApplicationDeploymentJob implements ShouldQueue, ShouldBeEncrypted
$git_clone_command = "GIT_SSH_COMMAND=\"ssh -o LogLevel=ERROR -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -i /root/.ssh/id_rsa\" {$git_clone_command} {$this->application->git_full_url} {$this->workdir}";
$git_clone_command = $this->set_git_import_settings($git_clone_command);
$commands = collect([
$this->execute_in_builder("mkdir -p /root/.ssh"),
$this->execute_in_builder("echo '{$private_key}' | base64 -d > /root/.ssh/id_rsa"),
$this->execute_in_builder("chmod 600 /root/.ssh/id_rsa"),
$this->execute_in_builder($git_clone_command)
executeInDocker($this->deployment_uuid, "mkdir -p /root/.ssh"),
executeInDocker($this->deployment_uuid, "echo '{$private_key}' | base64 -d > /root/.ssh/id_rsa"),
executeInDocker($this->deployment_uuid, "chmod 600 /root/.ssh/id_rsa"),
executeInDocker($this->deployment_uuid, $git_clone_command)
]);
return $commands->implode(' && ');
}
@@ -414,7 +410,7 @@ class ApplicationDeploymentJob implements ShouldQueue, ShouldBeEncrypted
private function cleanup_git()
{
$this->execute_remote_command(
[$this->execute_in_builder("rm -fr {$this->workdir}/.git")],
[executeInDocker($this->deployment_uuid, "rm -fr {$this->workdir}/.git")],
);
}
@@ -425,8 +421,8 @@ class ApplicationDeploymentJob implements ShouldQueue, ShouldBeEncrypted
"echo -n 'Generating nixpacks configuration.'",
],
[$this->nixpacks_build_cmd()],
[$this->execute_in_builder("cp {$this->workdir}/.nixpacks/Dockerfile {$this->workdir}/Dockerfile")],
[$this->execute_in_builder("rm -f {$this->workdir}/.nixpacks/Dockerfile")]
[executeInDocker($this->deployment_uuid, "cp {$this->workdir}/.nixpacks/Dockerfile {$this->workdir}/Dockerfile")],
[executeInDocker($this->deployment_uuid, "rm -f {$this->workdir}/.nixpacks/Dockerfile")]
);
}
@@ -444,7 +440,7 @@ class ApplicationDeploymentJob implements ShouldQueue, ShouldBeEncrypted
$nixpacks_command .= " --install-cmd \"{$this->application->install_command}\"";
}
$nixpacks_command .= " {$this->workdir}";
return $this->execute_in_builder($nixpacks_command);
return executeInDocker($this->deployment_uuid, $nixpacks_command);
}
private function generate_env_variables()
@@ -522,7 +518,7 @@ class ApplicationDeploymentJob implements ShouldQueue, ShouldBeEncrypted
}
$this->docker_compose = Yaml::dump($docker_compose, 10);
$this->docker_compose_base64 = base64_encode($this->docker_compose);
$this->execute_remote_command([$this->execute_in_builder("echo '{$this->docker_compose_base64}' | base64 -d > {$this->workdir}/docker-compose.yml"), "hidden" => true]);
$this->execute_remote_command([executeInDocker($this->deployment_uuid, "echo '{$this->docker_compose_base64}' | base64 -d > {$this->workdir}/docker-compose.yml"), "hidden" => true]);
}
private function generate_local_persistent_volumes()
@@ -679,7 +675,7 @@ class ApplicationDeploymentJob implements ShouldQueue, ShouldBeEncrypted
if ($this->application->settings->is_static) {
$this->execute_remote_command([
$this->execute_in_builder("docker build --network host -f {$this->workdir}/Dockerfile {$this->build_args} --progress plain -t $this->build_image_name {$this->workdir}"), "hidden" => true
executeInDocker($this->deployment_uuid, "docker build --network host -f {$this->workdir}/Dockerfile {$this->build_args} --progress plain -t $this->build_image_name {$this->workdir}"), "hidden" => true
]);
$dockerfile = base64_encode("FROM {$this->application->static_image}
@@ -706,18 +702,18 @@ COPY ./nginx.conf /etc/nginx/conf.d/default.conf");
}");
$this->execute_remote_command(
[
$this->execute_in_builder("echo '{$dockerfile}' | base64 -d > {$this->workdir}/Dockerfile-prod")
executeInDocker($this->deployment_uuid, "echo '{$dockerfile}' | base64 -d > {$this->workdir}/Dockerfile-prod")
],
[
$this->execute_in_builder("echo '{$nginx_config}' | base64 -d > {$this->workdir}/nginx.conf")
executeInDocker($this->deployment_uuid, "echo '{$nginx_config}' | base64 -d > {$this->workdir}/nginx.conf")
],
[
$this->execute_in_builder("docker build --network host -f {$this->workdir}/Dockerfile-prod {$this->build_args} --progress plain -t $this->production_image_name {$this->workdir}"), "hidden" => true
executeInDocker($this->deployment_uuid, "docker build --network host -f {$this->workdir}/Dockerfile-prod {$this->build_args} --progress plain -t $this->production_image_name {$this->workdir}"), "hidden" => true
]
);
} else {
$this->execute_remote_command([
$this->execute_in_builder("docker build --network host -f {$this->workdir}/Dockerfile {$this->build_args} --progress plain -t $this->production_image_name {$this->workdir}"), "hidden" => true
executeInDocker($this->deployment_uuid, "docker build --network host -f {$this->workdir}/Dockerfile {$this->build_args} --progress plain -t $this->production_image_name {$this->workdir}"), "hidden" => true
]);
}
}
@@ -727,7 +723,7 @@ COPY ./nginx.conf /etc/nginx/conf.d/default.conf");
if ($this->currently_running_container_name) {
$this->execute_remote_command(
["echo -n 'Removing old version of your application.'"],
[$this->execute_in_builder("docker rm -f $this->currently_running_container_name >/dev/null 2>&1"), "hidden" => true],
[executeInDocker($this->deployment_uuid, "docker rm -f $this->currently_running_container_name >/dev/null 2>&1"), "hidden" => true],
);
}
}
@@ -736,7 +732,7 @@ COPY ./nginx.conf /etc/nginx/conf.d/default.conf");
{
$this->execute_remote_command(
["echo -n 'Rolling update started.'"],
[$this->execute_in_builder("docker compose --project-directory {$this->workdir} up -d >/dev/null"), "hidden" => true],
[executeInDocker($this->deployment_uuid, "docker compose --project-directory {$this->workdir} up -d >/dev/null"), "hidden" => true],
);
}
@@ -759,7 +755,7 @@ COPY ./nginx.conf /etc/nginx/conf.d/default.conf");
private function add_build_env_variables_to_dockerfile()
{
$this->execute_remote_command([
$this->execute_in_builder("cat {$this->workdir}/Dockerfile"), "hidden" => true, "save" => 'dockerfile'
executeInDocker($this->deployment_uuid, "cat {$this->workdir}/Dockerfile"), "hidden" => true, "save" => 'dockerfile'
]);
$dockerfile = collect(Str::of($this->saved_outputs->get('dockerfile'))->trim()->explode("\n"));
@@ -768,7 +764,7 @@ COPY ./nginx.conf /etc/nginx/conf.d/default.conf");
}
$dockerfile_base64 = base64_encode($dockerfile->implode("\n"));
$this->execute_remote_command([
$this->execute_in_builder("echo '{$dockerfile_base64}' | base64 -d > {$this->workdir}/Dockerfile"),
executeInDocker($this->deployment_uuid, "echo '{$dockerfile_base64}' | base64 -d > {$this->workdir}/Dockerfile"),
"hidden" => true
]);
}

View File

@@ -18,7 +18,6 @@ use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\Middleware\WithoutOverlapping;
use Illuminate\Queue\SerializesModels;
use Throwable;
use Illuminate\Support\Str;
class DatabaseBackupJob implements ShouldQueue, ShouldBeEncrypted
@@ -117,7 +116,7 @@ class DatabaseBackupJob implements ShouldQueue, ShouldBeEncrypted
$this->backup_status = 'success';
$this->team->notify(new BackupSuccess($this->backup, $this->database));
} catch (Throwable $e) {
} catch (\Throwable $e) {
$this->backup_status = 'failed';
$this->add_to_backup_output($e->getMessage());
ray('Backup failed for ' . $this->container_name . ' at ' . $this->server->name . ':' . $this->backup_location . '\n\nError:' . $e->getMessage());

View File

@@ -4,8 +4,6 @@ namespace App\Notifications\Application;
use App\Models\Application;
use App\Models\ApplicationPreview;
use App\Notifications\Channels\DiscordChannel;
use App\Notifications\Channels\EmailChannel;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Notifications\Messages\MailMessage;
@@ -18,13 +16,14 @@ class DeploymentFailed extends Notification implements ShouldQueue
public $tries = 5;
public Application $application;
public string $deployment_uuid;
public ?ApplicationPreview $preview = null;
public string $deployment_uuid;
public string $application_name;
public ?string $deployment_url = null;
public string $project_uuid;
public string $environment_name;
public ?string $deployment_url = null;
public ?string $fqdn = null;
public function __construct(Application $application, string $deployment_uuid, ?ApplicationPreview $preview = null)

View File

@@ -4,8 +4,6 @@ namespace App\Notifications\Application;
use App\Models\Application;
use App\Models\ApplicationPreview;
use App\Notifications\Channels\DiscordChannel;
use App\Notifications\Channels\EmailChannel;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Notifications\Messages\MailMessage;
@@ -18,14 +16,15 @@ class DeploymentSuccess extends Notification implements ShouldQueue
public $tries = 5;
public Application $application;
public string $deployment_uuid;
public ApplicationPreview|null $preview = null;
public string $deployment_uuid;
public string $application_name;
public string|null $deployment_url = null;
public string $project_uuid;
public string $environment_name;
public string|null $fqdn;
public ?string $deployment_url = null;
public ?string $fqdn;
public function __construct(Application $application, string $deployment_uuid, ApplicationPreview|null $preview = null)
{

View File

@@ -2,8 +2,7 @@
namespace App\Notifications\Application;
use App\Notifications\Channels\DiscordChannel;
use App\Notifications\Channels\EmailChannel;
use App\Models\Application;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Notifications\Messages\MailMessage;
@@ -15,13 +14,14 @@ class StatusChanged extends Notification implements ShouldQueue
use Queueable;
public $tries = 5;
public $application;
public Application $application;
public string $application_name;
public string|null $application_url = null;
public string $project_uuid;
public string $environment_name;
public string|null $fqdn;
public ?string $application_url = null;
public ?string $fqdn;
public function __construct($application)
{

View File

@@ -11,7 +11,7 @@ use Illuminate\Support\Str;
trait ExecuteRemoteCommand
{
public string|null $save = null;
public ?string $save = null;
public function execute_remote_command(...$commands)
{
@@ -25,11 +25,8 @@ trait ExecuteRemoteCommand
throw new \RuntimeException('Server is not set or is not an instance of Server model');
}
$ip = data_get($this->server, 'ip');
$user = data_get($this->server, 'user');
$port = data_get($this->server, 'port');
$commandsText->each(function ($single_command) use ($ip, $user, $port) {
$commandsText->each(function ($single_command) {
$command = data_get($single_command, 'command') ?? $single_command[0] ?? null;
if ($command === null) {
throw new \RuntimeException('Command is not set');
@@ -38,7 +35,7 @@ trait ExecuteRemoteCommand
$ignore_errors = data_get($single_command, 'ignore_errors', false);
$this->save = data_get($single_command, 'save');
$remote_command = generateSshCommand( $ip, $user, $port, $command);
$remote_command = generateSshCommand($this->server, $command);
$process = Process::timeout(3600)->idleTimeout(3600)->start($remote_command, function (string $type, string $output) use ($command, $hidden) {
$output = Str::of($output)->trim();
$new_log_entry = [