diff --git a/app/Http/Controllers/InstallationController.php b/app/Http/Controllers/InstallationController.php new file mode 100644 index 00000000..977e25d0 --- /dev/null +++ b/app/Http/Controllers/InstallationController.php @@ -0,0 +1,39 @@ + + +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); + } + } +} \ No newline at end of file diff --git a/app/Services/InstallationScriptService.php b/app/Services/InstallationScriptService.php new file mode 100644 index 00000000..b7417d9c --- /dev/null +++ b/app/Services/InstallationScriptService.php @@ -0,0 +1,126 @@ + + +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; + } + } +} \ No newline at end of file diff --git a/routes/api.php b/routes/api.php index b707f495..cc550b50 100644 --- a/routes/api.php +++ b/routes/api.php @@ -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; /* |-------------------------------------------------------------------------- @@ -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']);