plugin installation in docker

This commit is contained in:
Arthur de Moulins
2020-03-13 15:53:15 +01:00
parent 0d7569439b
commit 23d757c4d6
9 changed files with 164 additions and 65 deletions

View File

@@ -23,7 +23,7 @@
/datas /datas
/docker-compose.* /docker-compose.*
/logs /logs
/nodes_modules /node_modules
/plugins /plugins
/tmp /tmp
/vendor /vendor

View File

@@ -90,6 +90,7 @@ RUN curl -sL https://deb.nodesource.com/setup_10.x | bash - \
telnet \ telnet \
autoconf \ autoconf \
libtool \ libtool \
python \
pkg-config \ pkg-config \
&& apt-get clean \ && apt-get clean \
&& rm -rf /var/lib/apt/lists \ && rm -rf /var/lib/apt/lists \
@@ -126,7 +127,7 @@ RUN ( \
&& chmod 600 ~/.ssh/id_rsa \ && chmod 600 ~/.ssh/id_rsa \
) || echo "Skip SSH key" ) || echo "Skip SSH key"
RUN ./docker/phraseanet/install-plugins RUN ./docker/phraseanet/plugins/console install
ENTRYPOINT ["/bootstrap/entrypoint.sh"] ENTRYPOINT ["/bootstrap/entrypoint.sh"]

View File

@@ -26,4 +26,6 @@ if [ ${XDEBUG_ENABLED} == "1" ]; then
docker-php-ext-enable xdebug docker-php-ext-enable xdebug
fi fi
./docker/phraseanet/plugins/console init
bash -e docker-php-entrypoint $@ bash -e docker-php-entrypoint $@

View File

@@ -1,50 +0,0 @@
#!/usr/bin/env php
<?php
function setupStreaming() {
// Turn off output buffering
ini_set('output_buffering', 'off');
// Turn off PHP output compression
ini_set('zlib.output_compression', false);
// Disable Apache output buffering/compression
if (function_exists('apache_setenv')) {
apache_setenv('no-gzip', '1');
apache_setenv('dont-vary', '1');
}
}
function runCommand($cmd){
echo "+ $cmd\n";
system($cmd, $return);
if (0 !== $return) {
throw new \Exception(sprintf('Error %d: %s', $return, $cmd));
}
}
setupStreaming();
$plugins = trim(getenv('PHRASEANET_PLUGINS'));
if (empty($plugins)) {
echo "No plugin to install... SKIP\n";
exit(0);
}
foreach (explode(' ', $plugins) as $key => $plugin) {
$plugin = trim($plugin);
$repo = $plugin;
$branch = 'master';
if (1 === preg_match('#^(.+)\(([^)]+)\)$#', $plugin, $matches)) {
$repo = $matches[1];
$branch = $matches[2];
}
$pluginTmpName = 'plugin' . $key;
$pluginPath = './plugin' . $key;
if (is_dir($pluginPath)) {
echo shell_exec(sprintf('rm -rf %s', $pluginPath));
}
echo sprintf("Installing %s (branch: %s)\n", $repo, $branch);
runCommand(sprintf('git clone --single-branch --branch %s %s %s', $branch, $repo, $pluginPath));
runCommand(sprintf('bin/setup plugins:add %s', $pluginPath));
echo shell_exec(sprintf('rm -rf %s', $pluginPath));
}

View File

@@ -0,0 +1,29 @@
<?php
namespace Alchemy\Docker\Plugins\Command;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
class InitCommand extends Command
{
protected function configure()
{
$this
->setName('init')
->setDescription('Initialize plugins');
}
protected function execute(InputInterface $input, OutputInterface $output)
{
foreach (glob('./plugins/*') as $dir) {
if (is_dir($dir)) {
$output->writeln(sprintf('Init <info>%s</info> plugin', basename($dir)));
SubCommand::run(sprintf('bin/setup plugin:add %s', $dir));
}
}
return 0;
}
}

View File

@@ -0,0 +1,64 @@
<?php
namespace Alchemy\Docker\Plugins\Command;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
class InstallCommand extends Command
{
protected function configure()
{
$this
->setName('install')
->setDescription('Install plugins');
}
protected function execute(InputInterface $input, OutputInterface $output)
{
$plugins = trim(getenv('PHRASEANET_PLUGINS'));
if (empty($plugins)) {
$output->writeln('<comment>No plugin to install... SKIP</comment>');
return 0;
}
$pluginsDir = 'plugins';
if (!is_dir($pluginsDir)) {
mkdir($pluginsDir);
}
foreach (explode(' ', $plugins) as $key => $plugin) {
$plugin = trim($plugin);
$repo = $plugin;
$branch = 'master';
if (1 === preg_match('#^(.+)\(([^)]+)\)$#', $plugin, $matches)) {
$repo = $matches[1];
$branch = $matches[2];
}
$pluginPath = './plugin' . $key;
if (is_dir($pluginPath)) {
SubCommand::run(sprintf('rm -rf %s', $pluginPath));
}
$output->writeln(sprintf('Installing <info>%s</info> (branch: <info>%s</info>)', $repo, $branch));
SubCommand::run(sprintf('git clone --single-branch --branch %s %s %s', $branch, $repo, $pluginPath));
$manifestSrc = $pluginPath.'/manifest.json';
if (!file_exists($manifestSrc)) {
throw new \Exception(sprintf('Cannot install plugin %s: no manifest.json file found', $plugin));
}
$pluginDestName = json_decode(file_get_contents($manifestSrc), true)['name'];
rename($pluginPath, $pluginsDir.'/'.$pluginDestName);
$pluginPath = $pluginsDir.'/'.$pluginDestName;
if (file_exists($pluginPath.'/composer.json')) {
SubCommand::run(sprintf('cd %s && composer install --no-dev', $pluginPath));
}
}
return 0;
}
}

View File

@@ -0,0 +1,26 @@
<?php
namespace Alchemy\Docker\Plugins\Command;
function setupStreaming()
{
ini_set('output_buffering', 'off');
ini_set('zlib.output_compression', false);
if (function_exists('apache_setenv')) {
apache_setenv('no-gzip', '1');
apache_setenv('dont-vary', '1');
}
}
setupStreaming();
abstract class SubCommand
{
static public function run($cmd)
{
system($cmd, $return);
if (0 !== $return) {
throw new \Exception(sprintf('Error %d: %s', $return, $cmd));
}
}
}

View File

@@ -0,0 +1,17 @@
#!/usr/bin/env php
<?php
namespace Alchemy\Docker\Plugins\Command;
require __DIR__.'/../../../vendor/autoload.php';
require __DIR__.'/SubCommand.php';
require __DIR__.'/InstallCommand.php';
require __DIR__.'/InitCommand.php';
use Symfony\Component\Console\Application;
$application = new Application();
$application->add(new InstallCommand());
$application->add(new InitCommand());
$application->run();

View File

@@ -54,33 +54,43 @@ abstract class AbstractPluginCommand extends Command
protected function doInstallPlugin($source, InputInterface $input, OutputInterface $output) protected function doInstallPlugin($source, InputInterface $input, OutputInterface $output)
{ {
$temporaryDir = $this->container['temporary-filesystem']->createTemporaryDirectory();
$output->write("Importing <info>$source</info>...");
$this->container['plugins.importer']->import($source, $temporaryDir);
$output->writeln(" <comment>OK</comment>");
$output->write("Validating plugin..."); $output->write("Validating plugin...");
$manifest = $this->container['plugins.plugins-validator']->validatePlugin($temporaryDir); $manifest = $this->container['plugins.plugins-validator']->validatePlugin($source);
$output->writeln(" <comment>OK</comment> found <info>".$manifest->getName()."</info>"); $output->writeln(" <comment>OK</comment> found <info>".$manifest->getName()."</info>");
$targetDir = $this->container['plugin.path'] . DIRECTORY_SEPARATOR . $manifest->getName(); $targetDir = $this->container['plugin.path'] . DIRECTORY_SEPARATOR . $manifest->getName();
if (realpath($targetDir) !== realpath($source)) {
$temporaryDir = $this->container['temporary-filesystem']->createTemporaryDirectory();
$output->write("Importing <info>$source</info>...");
$this->container['plugins.importer']->import($source, $temporaryDir);
$output->writeln(" <comment>OK</comment>");
$workingDir = $temporaryDir;
} else {
$workingDir = $targetDir;
}
$output->write("Setting up composer..."); if (!is_dir($workingDir.'/vendor')) {
$this->container['plugins.composer-installer']->install($temporaryDir); $output->write("Setting up composer...");
$output->writeln(" <comment>OK</comment>"); $this->container['plugins.composer-installer']->install($workingDir);
$output->writeln(" <comment>OK</comment>");
}
$output->write("Installing plugin <info>".$manifest->getName()."</info>..."); $output->write("Installing plugin <info>".$manifest->getName()."</info>...");
$this->container['filesystem']->mirror($temporaryDir, $targetDir); if (isset($temporaryDir)) {
$this->container['filesystem']->mirror($temporaryDir, $targetDir);
}
$output->writeln(" <comment>OK</comment>"); $output->writeln(" <comment>OK</comment>");
$output->write("Copying public files <info>".$manifest->getName()."</info>..."); $output->write("Copying public files <info>".$manifest->getName()."</info>...");
$this->container['plugins.assets-manager']->update($manifest); $this->container['plugins.assets-manager']->update($manifest);
$output->writeln(" <comment>OK</comment>"); $output->writeln(" <comment>OK</comment>");
$output->write("Removing temporary directory..."); if (isset($temporaryDir)) {
$this->container['filesystem']->remove($temporaryDir); $output->write("Removing temporary directory...");
$output->writeln(" <comment>OK</comment>"); $this->container['filesystem']->remove($temporaryDir);
$output->writeln(" <comment>OK</comment>");
}
$output->write("Activating plugin..."); $output->write("Activating plugin...");
$this->container['conf']->set(['plugins', $manifest->getName(), 'enabled'], true); $this->container['conf']->set(['plugins', $manifest->getName(), 'enabled'], true);