This commit is contained in:
Bozhidar 2024-05-15 12:59:08 +03:00
parent 22034da019
commit 366b3f8ad1
3 changed files with 200 additions and 3 deletions

127
web/app/ApacheParser.php Normal file
View file

@ -0,0 +1,127 @@
<?php
namespace App;
class ApacheParser
{
private static $commentRegex = '/#.*/i';
private static $directiveRegex = '/([^\\s]+)\\s*(.+)/i';
private static $sectionOpenRegex = '/<([^\\/\\s>]+)\\s*([^>]+)?>/i';
private static $sectionCloseRegex = '/<\\/([^\\s>]+)\\s*>/i';
public function parse($confPath)
{
if (empty($confPath)) {
throw new \Exception("Configuration path cannot be null or empty.");
}
if (!file_exists($confPath)) {
throw new \Exception("Configuration file not found: " . $confPath);
}
$currentNode = ConfigNode::createRootNode();
try {
$lines = file($confPath); // Don't add flags to file() function, this will broke line numbers (Line numbers are important for debugging)
$i = 0;
foreach ($lines as $line) {
$i++;
if (preg_match(self::$commentRegex, $line)) {
continue;
}
if (preg_match(self::$sectionOpenRegex, $line, $sectionOpenMatch)) {
$name = $sectionOpenMatch[1];
$content = isset($sectionOpenMatch[2]) ? $sectionOpenMatch[2] : '';
$sectionNode = ConfigNode::createChildNode($name, $content, $currentNode, $i);
$currentNode = $sectionNode;
} elseif (preg_match(self::$sectionCloseRegex, $line, $sectionCloseMatch)) {
$currentNode->endLine = $i;
$currentNode = $currentNode->getParent();
} elseif (preg_match(self::$directiveRegex, $line, $directiveMatch)) {
$name = $directiveMatch[1];
$content = $directiveMatch[2];
ConfigNode::createChildNode($name, $content, $currentNode, $i);
}
}
} catch (\Exception $e) {
throw new \Exception("An error occurred while reading the configuration file.", 0, $e);
}
return $currentNode;
}
}
class ConfigNode
{
private $name;
private $content;
private $parent;
private $children;
public $startLine;
public $endLine;
private function __construct($name, $content, $parent, $line = null)
{
$this->name = $name;
$this->content = $content;
$this->parent = $parent;
$this->children = [];
$this->startLine = $line;
}
public function getName()
{
return $this->name;
}
public function getContent()
{
return $this->content;
}
public function getStartLine()
{
return $this->startLine;
}
public function getEndLine()
{
return $this->endLine;
}
public static function createRootNode()
{
return new ConfigNode('root', null, null, null);
}
public static function createChildNode($name, $content, $parent, $line = null)
{
$node = new ConfigNode($name, $content, $parent, $line);
if ($parent !== null) {
$parent->children[] = $node;
}
return $node;
}
public function getParent()
{
return $this->parent;
}
public function getChildren()
{
return $this->children;
}
public function __toString()
{
return trim($this->name . ' ' . $this->content);
}
}

View file

@ -2,12 +2,16 @@
namespace app\Console\Commands;
use App\ApacheParser;
use App\Jobs\ApacheBuild;
use App\Models\Backup;
use App\Models\Domain;
use App\Models\HostingSubscription;
use Carbon\Carbon;
use Illuminate\Console\Command;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
use Illuminate\Support\Str;
class RunRepair extends Command
{
@ -48,11 +52,76 @@ class RunRepair extends Command
if (strpos($checkSupervisorStatus, 'active (running)') !== false) {
$this->info('Supervisor is running');
} else {
$this->info('Supervisor is not running');
$this->info('Restarting supervisor');
shell_exec('service supervisor restart');
$this->info('Supervisor is not running. Please check supervisor status');
}
$this->fixApacheErrors();
}
public function fixApacheErrors()
{
// Restart Apache
shell_exec('service apache2 restart');
$checkApacheStatus = shell_exec('service apache2 status');
if (strpos($checkApacheStatus, 'Syntax error on line') !== false) {
$apacheErrorLine = null;
preg_match('/Syntax error on line (\d+)/', $checkApacheStatus, $matchApacheErrorLine);
if (isset($matchApacheErrorLine[1]) && is_numeric($matchApacheErrorLine[1])) {
$apacheErrorLine = $matchApacheErrorLine[1];
}
$apacheBrokenVirtualHosts = [];
$parser = new ApacheParser();
$configNode = $parser->parse('/etc/apache2/apache2.conf');
$configChildren = $configNode->getChildren();
foreach ($configChildren as $child) {
if ($child->getName() == 'VirtualHost') {
$virtualHost = [
'startLine' => $child->getStartLine(),
'endLine' => $child->getEndLine(),
'content' => $child->getContent()
];
$childChildren = $child->getChildren();
if (isset($childChildren[0])) {
foreach ($childChildren as $childChild) {
$virtualHost[$childChild->getName()] = $childChild->getContent();
}
}
if ($child->getStartLine() <= $apacheErrorLine && $child->getEndLine() >= $apacheErrorLine) {
$apacheBrokenVirtualHosts[] = $virtualHost;
}
}
}
if (count($apacheBrokenVirtualHosts) > 0) {
$this->error('Broken virtual hosts found');
foreach ($apacheBrokenVirtualHosts as $brokenVirtualHost) {
$this->error('Virtual host found: ' . $brokenVirtualHost['ServerName']);
$this->error('Turn on maintenance mode: ' . $brokenVirtualHost['ServerName']);
$findDomain = Domain::where('domain', $brokenVirtualHost['ServerName'])->first();
if ($findDomain) {
$findDomain->status = Domain::STATUS_SUSPENDED;
$findDomain->save();
}
}
$this->info('Run apache build...');
$apacheBuild = new ApacheBuild();
$apacheBuild->handle();
}
}
shell_exec('service apache2 restart');
$newCheckApacheStatus = shell_exec('service apache2 status');
if (Str::contains($newCheckApacheStatus, 'active (running)')) {
$this->info('Apache is running');
} else {
$this->info('Apache is not running. Please check apache status');
}
}
}

View file

@ -77,5 +77,6 @@ class ApacheBuild implements ShouldQueue
file_put_contents('/etc/apache2/apache2.conf', $apache2);
shell_exec('systemctl reload apache2');
}
}