App
This commit is contained in:
117
app/src/Command/Create.php
Normal file
117
app/src/Command/Create.php
Normal file
@ -0,0 +1,117 @@
|
||||
<?php
|
||||
namespace ProVM\ComposeManager\Command;
|
||||
|
||||
use Symfony\Component\Console;
|
||||
|
||||
#[Console\Attribute\AsCommand(
|
||||
name: 'create'
|
||||
)]
|
||||
class Create extends Console\Command\Command
|
||||
{
|
||||
public function __construct(protected string $root, protected string $output, ?string $name = null)
|
||||
{
|
||||
parent::__construct($name);
|
||||
}
|
||||
|
||||
protected function configure(): void
|
||||
{
|
||||
$this->addArgument('name', Console\Input\InputArgument::REQUIRED, 'Name of the project, same as project folder where docker compose file is located');
|
||||
$this->addOption('group', 'g', Console\Input\InputOption::VALUE_REQUIRED, "Sub-path to the project folder relative to the root {$this->root}");
|
||||
$this->addOption('description', 'd', Console\Input\InputOption::VALUE_REQUIRED, 'Description of the project');
|
||||
$this->addOption('remove-orphans', 'r', Console\Input\InputOption::VALUE_NONE, 'Remove containers for services not defined in the Compose file');
|
||||
}
|
||||
|
||||
protected function execute(Console\Input\InputInterface $input, Console\Output\OutputInterface $output): int
|
||||
{
|
||||
$filename = implode(DIRECTORY_SEPARATOR, [rtrim($this->output, '/'), "docker-{$input->getArgument('name')}.service"]);
|
||||
$after = 'docker.service';
|
||||
|
||||
$sourceParts = [rtrim($this->root, '/')];
|
||||
if ($input->hasOption('group') and $input->getOption('group')) {
|
||||
$sourceParts[] = $input->getOption('group');
|
||||
$after = $this->getGroupServiceName($input->getOption('group'));
|
||||
if (!$this->checkGroupFile($input->getOption('group'))) {
|
||||
$this->buildGroupFile($input->getOption('group'));
|
||||
}
|
||||
}
|
||||
$sourceParts[] = $input->getArgument('name');
|
||||
$source = implode(DIRECTORY_SEPARATOR, $sourceParts);
|
||||
|
||||
|
||||
if ($input->hasOption('description') and $input->getOption('description')) {
|
||||
$description = $input->getOption('description');
|
||||
} else {
|
||||
$descriptionParts = [];
|
||||
if ($input->hasOption('group') and $input->getOption('group')) {
|
||||
$descriptionParts[] = $input->getOption('group');
|
||||
}
|
||||
$descriptionParts[] = $input->getArgument('name');
|
||||
$description = "Docker Compose service for " . implode(DIRECTORY_SEPARATOR, $descriptionParts);
|
||||
}
|
||||
|
||||
$content = $this->buildServiceFile($source, $description, $after, $input->getOption('remove-orphans'));
|
||||
|
||||
file_put_contents($filename, $content);
|
||||
|
||||
return Console\Command\Command::SUCCESS;
|
||||
}
|
||||
|
||||
protected function buildServiceFile(string $source, string $description, string $after = 'docker.service', bool $removeOrphans = false): string
|
||||
{
|
||||
$removeOrphans = $removeOrphans ? ' --remove-orphans' : '';
|
||||
|
||||
return <<<SERVICE
|
||||
[Unit]
|
||||
Description={$description}
|
||||
PartOf={$after}
|
||||
After={$after}
|
||||
Before=docker-services.target
|
||||
|
||||
[Service]
|
||||
Type=oneshot
|
||||
RemainAfterExit=yes
|
||||
WorkingDirectory={$source}
|
||||
ExecStart=/usr/local/bin/docker-compose up -d
|
||||
ExecStop=/usr/local/bin/docker-compose down{$removeOrphans}
|
||||
|
||||
[Install]
|
||||
RequiredBy=docker-services.target
|
||||
|
||||
SERVICE;
|
||||
}
|
||||
|
||||
protected function getGroupServiceName(string $groupName): string
|
||||
{
|
||||
return "docker-{$groupName}.service";
|
||||
}
|
||||
protected function checkGroupFile(string $groupName): bool
|
||||
{
|
||||
$filename = implode(DIRECTORY_SEPARATOR, [rtrim($this->output, '/'), $this->getGroupServiceName($groupName)]);
|
||||
return file_exists($filename);
|
||||
}
|
||||
protected function buildGroupFile(string $groupName): void
|
||||
{
|
||||
$filename = implode(DIRECTORY_SEPARATOR, [rtrim($this->output, '/'), $this->getGroupServiceName($groupName)]);
|
||||
$content = $this->buildGroupServiceFile($groupName);
|
||||
file_put_contents($filename, $content);
|
||||
}
|
||||
protected function buildGroupServiceFile(string $groupName): string
|
||||
{
|
||||
return <<<SERVICE
|
||||
[Unit]
|
||||
Description=Docker Compose service for group {$groupName}
|
||||
PartOf=docker.service
|
||||
After=docker.service
|
||||
Before=docker-services.target
|
||||
|
||||
[Service]
|
||||
Type=oneshot
|
||||
RemainAfterExit=yes
|
||||
WorkingDirectory={$this->root}/{$groupName}
|
||||
ExecStart=/bin/true
|
||||
|
||||
[Install]
|
||||
RequiredBy=docker-services.target
|
||||
SERVICE;
|
||||
}
|
||||
}
|
19
app/src/Wrapper/Application.php
Normal file
19
app/src/Wrapper/Application.php
Normal file
@ -0,0 +1,19 @@
|
||||
<?php
|
||||
namespace ProVM\ComposeManager\Wrapper;
|
||||
|
||||
use Psr\Container\ContainerInterface;
|
||||
use Symfony\Component\Console;
|
||||
|
||||
class Application extends Console\Application
|
||||
{
|
||||
protected ContainerInterface $container;
|
||||
public function getContainer(): ContainerInterface
|
||||
{
|
||||
return $this->container;
|
||||
}
|
||||
public function setContainer(ContainerInterface $container): Application
|
||||
{
|
||||
$this->container = $container;
|
||||
return $this;
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user