From 366b3f8ad1dd7438c690c857de00b8a9e396cfff Mon Sep 17 00:00:00 2001 From: Bozhidar Date: Wed, 15 May 2024 12:59:08 +0300 Subject: [PATCH] update --- web/app/ApacheParser.php | 127 +++++++++++++++++++++++++ web/app/Console/Commands/RunRepair.php | 75 ++++++++++++++- web/app/Jobs/ApacheBuild.php | 1 + 3 files changed, 200 insertions(+), 3 deletions(-) create mode 100644 web/app/ApacheParser.php diff --git a/web/app/ApacheParser.php b/web/app/ApacheParser.php new file mode 100644 index 0000000..e75e53c --- /dev/null +++ b/web/app/ApacheParser.php @@ -0,0 +1,127 @@ +]+)\\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); + } +} diff --git a/web/app/Console/Commands/RunRepair.php b/web/app/Console/Commands/RunRepair.php index 106da16..3287c72 100644 --- a/web/app/Console/Commands/RunRepair.php +++ b/web/app/Console/Commands/RunRepair.php @@ -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'); + } + } } diff --git a/web/app/Jobs/ApacheBuild.php b/web/app/Jobs/ApacheBuild.php index c609446..cd5b643 100644 --- a/web/app/Jobs/ApacheBuild.php +++ b/web/app/Jobs/ApacheBuild.php @@ -77,5 +77,6 @@ class ApacheBuild implements ShouldQueue file_put_contents('/etc/apache2/apache2.conf', $apache2); shell_exec('systemctl reload apache2'); + } }