Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 14 additions & 4 deletions CommonLogic/AppInstallers/AbstractServerInstaller.php
Original file line number Diff line number Diff line change
Expand Up @@ -57,8 +57,13 @@ protected abstract function getConfigTemplatePathRelative() : string;
* @return string
*/
protected abstract function stringToComment(string $comment) : string;

/**
* @return string
*/
protected abstract function ServerSoftwareFamilyDefault() : string;

/**
*
* {@inheritDoc}
* @see \exface\Core\Interfaces\InstallerInterface::backup()
Expand Down Expand Up @@ -87,10 +92,15 @@ public function install(string $source_absolute_path): \Iterator
{
$indentOuter = $this->getOutputIndentation();
$indent = $indentOuter . $indentOuter;
$serverType = ServerSoftwareDataType::getServerSoftwareFamily() ?? 'UNKNOWN SERVER SOFTWARE';
$serverVersion = ServerSoftwareDataType::getServerSoftwareVersion() ?? 'UNKNOWN VERSION';

yield $indentOuter . "Server configuration for {$serverType} {$serverVersion}:" . PHP_EOL;
$serverType = ServerSoftwareDataType::getServerSoftwareFamily() ??
$this->ServerSoftwareFamilyDefault() ??
'UNKNOWN SERVER SOFTWARE';

$serverVersion = ServerSoftwareDataType::getServerSoftwareVersion() ??
'with unknown version';

yield $indentOuter . "Loading server configuration for \"{$serverType}\" {$serverVersion}:" . PHP_EOL;

$this->configInstaller->setOutputIndentation($indent);
yield $indent . "Using \"{$this->getConfigTemplatePathRelative()}\" template for {$serverType}." . PHP_EOL;
Expand Down
8 changes: 8 additions & 0 deletions CommonLogic/AppInstallers/ApacheServerInstaller.php
Original file line number Diff line number Diff line change
Expand Up @@ -97,4 +97,12 @@ protected function stringToComment(string $comment): string
{
return "# {$comment}";
}

/**
* @inheritDoc
*/
protected function ServerSoftwareFamilyDefault(): string
{
return 'Apache';
}
}
28 changes: 28 additions & 0 deletions CommonLogic/AppInstallers/AppInstallerContainer.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

use exface\Core\DataTypes\DateTimeDataType;
use exface\Core\Interfaces\AppInstallerInterface;
use exface\Core\Interfaces\IAmSilentInterface;
use exface\Core\Interfaces\InstallerInterface;
use exface\Core\Interfaces\InstallerContainerInterface;
use exface\Core\Events\Installer\OnBeforeInstallEvent;
Expand Down Expand Up @@ -44,6 +45,11 @@ public final function install(string $source_absolute_path) : \Iterator

$eventMgr = $this->getWorkbench()->eventManager();
foreach ($this->getInstallers() as $installer) {
if($installer instanceof IAmSilentInterface) {
yield from $installer->install($source_absolute_path);
continue;
}

$eventMgr->dispatch(new OnBeforeInstallEvent($installer, $source_absolute_path));
yield from $installer->install($source_absolute_path);
$eventMgr->dispatch(new OnInstallEvent($installer, $source_absolute_path));
Expand Down Expand Up @@ -93,6 +99,11 @@ public final function backup(string $destination_absolute_path) : \Iterator

$eventMgr = $this->getWorkbench()->eventManager();
foreach ($this->getInstallers() as $installer) {
if($installer instanceof IAmSilentInterface) {
yield from $installer->backup($destination_absolute_path);
continue;
}

$eventMgr->dispatch(new OnBeforeBackupEvent($installer, $destination_absolute_path));
yield from $installer->backup($destination_absolute_path);
$eventMgr->dispatch(new OnBackupEvent($installer, $destination_absolute_path));
Expand All @@ -117,6 +128,11 @@ public final function uninstall() : \Iterator
// TODO disable mutations here too???
$eventMgr = $this->getWorkbench()->eventManager();
foreach (array_reverse($this->getInstallers()) as $installer) {
if($installer instanceof IAmSilentInterface) {
yield from $installer->uninstall();
continue;
}

$eventMgr->dispatch(new OnBeforeUninstallEvent($installer));
yield from $installer->uninstall();
$eventMgr->dispatch(new OnUninstallEvent($installer));
Expand Down Expand Up @@ -161,4 +177,16 @@ public function extract(callable $filterCallback) : InstallerContainerInterface
}
return $container;
}

/**
* @inheritDoc
*/
public function addMessage(string $message, bool $insertAtBeginning = false) : InstallerContainerInterface
{
if($message !== '') {
$this->addInstaller(new DebugInstaller($this->getWorkbench(), $message), $insertAtBeginning);
}

return $this;
}
}
95 changes: 95 additions & 0 deletions CommonLogic/AppInstallers/DebugInstaller.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
<?php

namespace exface\Core\CommonLogic\AppInstallers;

use exface\Core\Interfaces\InstallerInterface;
use exface\Core\Interfaces\IAmSilentInterface;
use exface\Core\Interfaces\WorkbenchInterface;

/**
* An empty installer that does not perform any work. You can pass an optional message to be yielded
* whenever `install()`, `backup()` or `uninstall()` is called.
*
* You can use this installer as a stub or to inject debugging messages and logging into your deployment logic.
*/
class DebugInstaller implements InstallerInterface, IAmSilentInterface
{
private WorkbenchInterface $workbench;
private ?string $message;
private string $indent;

function __construct(
WorkbenchInterface $workbench,
string $message = null,
string $indent = ' '
)
{
$this->workbench = $workbench;
$this->indent = $indent;
$this->message = str_ends_with($message, PHP_EOL) ? $message : $message . PHP_EOL;
}

/**
* @inheritDoc
*/
public function install(string $source_absolute_path): \Iterator
{
yield $this->getMessage() ?? new \EmptyIterator();
}

/**
* @inheritDoc
*/
public function backup(string $absolute_path): \Iterator
{
yield $this->getMessage() ?? new \EmptyIterator();
}

/**
* @inheritDoc
*/
public function uninstall(): \Iterator
{
yield $this->getMessage() ?? new \EmptyIterator();
}

/**
* STUB! Do not use.
* @deprecated
*/
public function getWorkbench() : WorkbenchInterface
{
return $this->workbench;
}

/**
* @return string
*/
public function getOutputIndentation() : string
{
return $this->indent;
}

/**
* @param string $value
* @return $this
*/
public function setOutputIndentation(string $value) : DebugInstaller
{
$this->indent = $value;
return $this;
}

/**
* @param bool $withIndentation
* @return string|null
*/
public function getMessage(bool $withIndentation = true) : ?string
{
if($this->message === null) {
return null;
}

return $this->getOutputIndentation() . $this->message;
}
}
8 changes: 8 additions & 0 deletions CommonLogic/AppInstallers/IISServerInstaller.php
Original file line number Diff line number Diff line change
Expand Up @@ -82,4 +82,12 @@ protected function stringToComment(string $comment): string
{
return "<!-- {$comment} -->";
}

/**
* @inheritDoc
*/
protected function ServerSoftwareFamilyDefault(): string
{
return 'Microsoft-IIS';
}
}
8 changes: 8 additions & 0 deletions CommonLogic/AppInstallers/NginxServerInstaller.php
Original file line number Diff line number Diff line change
Expand Up @@ -87,4 +87,12 @@ protected function stringToComment(string $comment): string
{
return "# {$comment}";
}

/**
* @inheritDoc
*/
protected function ServerSoftwareFamilyDefault(): string
{
return 'nginx';
}
}
51 changes: 37 additions & 14 deletions CoreApp.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@

use exface\Core\CommonLogic\AppInstallers\ApacheServerInstaller;
use exface\Core\CommonLogic\AppInstallers\AppDocsInstaller;
use exface\Core\CommonLogic\AppInstallers\AppInstallerContainer;
use exface\Core\CommonLogic\AppInstallers\NginxServerInstaller;
use exface\Core\Exceptions\Installers\InstallerRuntimeError;
use exface\Core\Facades\PermalinkFacade;
use exface\Core\Interfaces\InstallerInterface;
use exface\Core\Factories\ConfigurationFactory;
Expand Down Expand Up @@ -106,17 +106,14 @@ public function getInstaller(InstallerInterface $injected_installer = null)
$installer->addInstaller($tplInstaller);

// Server installer.
$serverInstallerClass = $this->getServerInstallerClass();
$serverInstallerClass = $this->getServerInstallerClass($installer);
if ($serverInstallerClass !== null) {
$serverInstaller = new $serverInstallerClass($this->getSelector());
$installer->addInstaller($serverInstaller);
} else {
$msg = 'Could not determine server installer class! Consider defining the server installer class ' .
'explicitly by setting "' . self::CONFIG_SERVER_INSTALLER . '" in "System.config.json".';

throw new InstallerRuntimeError(
$installer,
$msg
$installer->addMessage('FAILED - Could not determine server installer class! Consider defining the' .
' server installer class explicitly by setting "' . self::CONFIG_SERVER_INSTALLER .
'" in "System.config.json".'
);
}

Expand All @@ -134,18 +131,28 @@ public function getInstaller(InstallerInterface $injected_installer = null)
}

/**
* @param AppInstallerContainer $installer
* @return string|null
*/
protected function getServerInstallerClass() : string|null
protected function getServerInstallerClass(AppInstallerContainer $installer) : string|null
{
$installer->addMessage('Determining server installer class:');
$indent = ' ';

// From config option.
$cfg = $this->getWorkbench()->getConfig();
if($cfg->hasOption(self::CONFIG_SERVER_INSTALLER)) {
$configOption = $this->getWorkbench()->getConfig()->getOption(self::CONFIG_SERVER_INSTALLER);

if(!empty($configOption)) {

// Valid-ish config option.
if(class_exists($configOption)) {
$installer->addMessage($indent . 'Found installer class in config: "' . $configOption . '".');
return $configOption;
}
}

// Invalid config option.
$installer->addMessage($indent . 'Value "' . $configOption . '" for config option "' .
self::CONFIG_SERVER_INSTALLER . '" is not a valid class name.');
}

// Read from PHP constant.
Expand All @@ -155,6 +162,9 @@ protected function getServerInstallerClass() : string|null
// Future installations should have a manually defined ``
if(empty($softwareFamily)) {
$path = $this->getWorkbench()->getInstallationPath();
$installer->addMessage($indent . 'Deducing server software from installation path "' . $path .
'" under "' . php_uname('s') . '".');

$softwareFamily = match (true) {
// Microsoft IIS runs on windows and has its files mostly in c:\inetpub\wwwroot
ServerSoftwareDataType::isOsWindows() && preg_match('/[Cc]:\\\\inetpub\\\\wwwroot\\\\/', $path) === 1 => ServerSoftwareDataType::SERVER_SOFTWARE_IIS,
Expand All @@ -165,18 +175,31 @@ protected function getServerInstallerClass() : string|null
ServerSoftwareDataType::isOsLinux() && preg_match("/\/www\//", $path) === 1 => ServerSoftwareDataType::SERVER_SOFTWARE_APACHE,
default => null
};

if(empty($softwareFamily)) {
$installer->addMessage($indent . 'Could not determine server software.');
return null;
} else {
$installer->addMessage($indent . 'Server software from folder structure: "' . $softwareFamily . '".');
}
} else {
$installer->addMessage($indent . 'Server software from PHP constant: "' . $softwareFamily . '".');
}

return match ($softwareFamily) {
$class = match ($softwareFamily) {
ServerSoftwareDataType::SERVER_SOFTWARE_APACHE => '\\' . ltrim(ApacheServerInstaller::class, "\\"),
ServerSoftwareDataType::SERVER_SOFTWARE_IIS => '\\' . ltrim(IISServerInstaller::class, "\\"),
ServerSoftwareDataType::SERVER_SOFTWARE_NGINX => '\\' . ltrim(NginxServerInstaller::class, "\\"),
default => null
};

if($class !== null) {
$installer->addMessage($indent . 'Deduced installer class from server software: "' . $class . '".');
} else {
$installer->addMessage($indent . 'Could not deduce server installer class.');
}

return $class;
}

/**
Expand Down
18 changes: 18 additions & 0 deletions Interfaces/IAmSilentInterface.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<?php

namespace exface\Core\Interfaces;

use exface\Core\CommonLogic\AppInstallers\AppInstallerContainer;

/**
* An empty marker interface. Systems that recognize this interface will not dispatch events
* when processing objects that implement it.
*
* NOTE: The exact behavior depends on the system and is not guaranteed.
*
* @see AppInstallerContainer
*/
interface IAmSilentInterface
{

}
14 changes: 13 additions & 1 deletion Interfaces/InstallerContainerInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,24 @@ public function addInstaller(InstallerInterface $installer, $insertAtBeinning =
* @return InstallerInterface[]
*/
public function getInstallers() : array;

/**
* Returns a new installer container with only installers matching the ginve filter
*
* @param callable $filterCallback
* @return InstallerContainerInterface
*/
public function extract(callable $filterCallback) : InstallerContainerInterface;

/**
* Adds a message to be displayed when performing `install()`, `backup()` or `uninstall()`.
*
* NOTE: Adding a message is similar to adding an installer. Both use the same queue. Adding a message
* just before adding an installer means, that this message will always be displayed before that installer
* is executed.
*
* @param string $message
* @return InstallerContainerInterface
*/
public function addMessage(string $message) : InstallerContainerInterface;
}