Skip to content

Commit

Permalink
Merge pull request #334 from liberu-billing/sweep/Add-Laravel-Applica…
Browse files Browse the repository at this point in the history
…tion-Installation-Script-Service

Add Laravel Application Installation Script Service
  • Loading branch information
curtisdelicata authored Dec 25, 2024
2 parents 2926e67 + b9d0c4c commit 955cc59
Show file tree
Hide file tree
Showing 3 changed files with 169 additions and 0 deletions.
39 changes: 39 additions & 0 deletions app/Http/Controllers/InstallationController.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@


<?php

namespace App\Http\Controllers;

use App\Services\InstallationScriptService;
use Illuminate\Http\Request;

class InstallationController extends Controller
{
public function install(Request $request)
{
$validated = $request->validate([
'control_panel' => 'required|string|in:cpanel,plesk,directadmin,virtualmin',
'git_repo' => 'required|url',
'domain' => 'required|string',
'db_name' => 'required|string',
'db_user' => 'required|string',
'db_password' => 'required|string',
]);

$installer = new InstallationScriptService(
$validated['control_panel'],
$validated['git_repo'],
$validated['domain'],
$validated['db_name'],
$validated['db_user'],
$validated['db_password']
);

try {
$installer->execute();
return response()->json(['message' => 'Installation completed successfully']);
} catch (\Exception $e) {
return response()->json(['error' => $e->getMessage()], 500);
}
}
}
126 changes: 126 additions & 0 deletions app/Services/InstallationScriptService.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@


<?php

namespace App\Services;

use Exception;
use Illuminate\Support\Facades\File;
use Illuminate\Support\Facades\Log;

class InstallationScriptService
{
protected $controlPanel;
protected $gitRepo;
protected $domain;
protected $dbName;
protected $dbUser;
protected $dbPass;

public function __construct($controlPanel, $gitRepo, $domain, $dbName, $dbUser, $dbPass)
{
$this->controlPanel = strtolower($controlPanel);
$this->gitRepo = $gitRepo;
$this->domain = $domain;
$this->dbName = $dbName;
$this->dbUser = $dbUser;
$this->dbPass = $dbPass;
}

public function generateScript()
{
$installDir = "~/laravel-apps/{$this->domain}";
$publicHtmlPath = $this->getPublicHtmlPath();

$script = [
'#!/bin/bash',
'set -e',
'',
'# Create installation directory',
"mkdir -p {$installDir}",
"cd {$installDir}",
'',
'# Clone repository',
"git clone {$this->gitRepo} .",
'',
'# Install composer dependencies',
'composer install --no-dev --optimize-autoloader',
'',
'# Install npm dependencies and build assets',
'npm install',
'npm run build',
'',
'# Setup Laravel environment',
'cp .env.example .env',
"sed -i 's/DB_DATABASE=.*/DB_DATABASE={$this->dbName}/' .env",
"sed -i 's/DB_USERNAME=.*/DB_USERNAME={$this->dbUser}/' .env",
"sed -i 's/DB_PASSWORD=.*/DB_PASSWORD={$this->dbPass}/' .env",
'',
'# Generate application key',
'php artisan key:generate',
'',
'# Create storage link',
'php artisan storage:link',
'',
'# Run migrations and seeders',
'php artisan migrate --force',
'php artisan db:seed --force',
'',
'# Set proper permissions',
'find . -type f -exec chmod 644 {} \\;',
'find . -type d -exec chmod 755 {} \\;',
'chmod -R 775 storage bootstrap/cache',
'',
'# Create symbolic link',
"ln -sf {$installDir}/public {$publicHtmlPath}",
'',
'echo "Installation completed successfully!"'
];

return implode("\n", $script);
}

protected function getPublicHtmlPath()
{
switch ($this->controlPanel) {
case 'cpanel':
return "~/public_html";
case 'plesk':
return "~/httpdocs";
case 'directadmin':
return "~/domains/{$this->domain}/public_html";
case 'virtualmin':
return "~/public_html";
default:
throw new Exception("Unsupported control panel: {$this->controlPanel}");
}
}

public function execute()
{
try {
$script = $this->generateScript();
$scriptPath = tempnam(sys_get_temp_dir(), 'laravel_install_');

File::put($scriptPath, $script);
chmod($scriptPath, 0755);

$output = shell_exec($scriptPath . " 2>&1");
unlink($scriptPath);

Log::info("Installation script executed successfully", [
'domain' => $this->domain,
'output' => $output
]);

return true;
} catch (Exception $e) {
Log::error("Installation script failed", [
'domain' => $this->domain,
'error' => $e->getMessage()
]);

throw $e;
}
}
}
4 changes: 4 additions & 0 deletions routes/api.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
use App\Http\Controllers\Api\SubscriptionController;
use App\Http\Controllers\Api\CustomerController;
use App\Http\Controllers\ClientNoteController;
use App\Http\Controllers\InstallationController;

/*
|--------------------------------------------------------------------------
Expand All @@ -29,6 +30,9 @@
return $request->user();
});

// Installation endpoint
Route::post('/install', [InstallationController::class, 'install']);

// Invoice endpoints
Route::apiResource('invoices', InvoiceController::class);
Route::get('invoices/{invoice}/download', [InvoiceController::class, 'download']);
Expand Down

0 comments on commit 955cc59

Please sign in to comment.