Skip to content

Commit

Permalink
fix: runner and change env
Browse files Browse the repository at this point in the history
  • Loading branch information
praswicaksono committed Nov 13, 2024
1 parent 5374a79 commit a40da03
Show file tree
Hide file tree
Showing 14 changed files with 126 additions and 79 deletions.
2 changes: 1 addition & 1 deletion .env
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
# https://symfony.com/doc/current/best_practices.html#use-environment-variables-for-infrastructure-configuration

###> symfony/framework-bundle ###
APP_ENV=dev
APP_ENV=prod
DEBUG=false
APP_SECRET=492b03606caaf81ffddde5780f4baf6c
###< symfony/framework-bundle ###
2 changes: 1 addition & 1 deletion box.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"main": "bin/mager",
"directories": ["config", "src", "vendor", "var"],
"directories": ["config", "src", "vendor", "var", "helpers"],
"files": [".env"],
"finder": [
{
Expand Down
5 changes: 4 additions & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,10 @@
"autoload": {
"psr-4": {
"App\\": "src/"
}
},
"files": [
"helpers/functions.php"
]
},
"autoload-dev": {
"psr-4": {
Expand Down
51 changes: 51 additions & 0 deletions helpers/functions.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
<?php
declare(strict_types=1);

use App\Component\Config\Json;
use App\Component\TaskRunner\RunnerBuilder;
use App\Component\TaskRunner\TaskInterface;
use Symfony\Component\Console\Input\StringInput;
use Symfony\Component\Console\Output\ConsoleOutput;
use Symfony\Component\Console\Style\SymfonyStyle;

function run(callable|string|TaskInterface $command, string $on, $local = false, $managerOnly = false, $workerOnly = false, $showProgress = true, $throwError = true): mixed
{
$io = new SymfonyStyle(
new StringInput(''),
new ConsoleOutput()
);
$home = getenv('HOME');

$runner = RunnerBuilder::create()
->withIO($io)
->withConfig(Json::fromFile("{$home}/.mager/config.json"));

if ($managerOnly) {
$runner = $runner->onManagerOnly(true)->onSingleManagerServer(true);
}

if ($workerOnly) {
$runner = $runner->onWorkerOnly(true);
}

$runner = $runner->build($on, local: $local);

$generator = match(true) {
$command instanceof TaskInterface || is_string($command) => (fn() => yield $command)(),
default => $command()
};

return $runner->run($generator, showProgress: $showProgress, throwError: $throwError);
}

function runLocally(callable|string|TaskInterface $command, $showProgress = true, $throwError = true): mixed {
return run($command, 'local', local: true, showProgress: $showProgress, throwError: $throwError);
}

function runOnManager(callable|string|TaskInterface $command, string $on, $showProgress = true, $throwError = true): mixed {
return run($command, $on, managerOnly: true, showProgress: $showProgress, throwError: $throwError);
}

function runOnWorker(callable|string|TaskInterface $command, string $on, $showProgress = true, $throwError = true): mixed {
return run($command, $on, workerOnly: true, showProgress: $showProgress, throwError: $throwError);
}
18 changes: 6 additions & 12 deletions src/Command/AppInstallCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@
use App\Component\Config\Config;
use App\Component\Config\Definition\ProxyPort;
use App\Component\Config\YamlAppServiceDefinitionBuilder;
use App\Component\TaskRunner\RunnerBuilder;
use App\Component\TaskRunner\TaskBuilder\DockerCreateService;
use App\Helper\CommandHelper;
use App\Helper\HttpHelper;
Expand All @@ -25,7 +24,7 @@

#[AsCommand(
name: 'app:install',
description: 'Install 3rd party apps',
description: 'Install third party apps',
)]
final class AppInstallCommand extends Command
{
Expand All @@ -42,13 +41,13 @@ protected function configure(): void
$this->addArgument(
'namespace',
InputArgument::REQUIRED,
'Deploy service to servers that listed for given namespace',
'Namespace',
);

$this->addArgument(
'url',
InputArgument::REQUIRED,
'URL package for 3rd party apps',
'URL package for third party apps',
);
}

Expand All @@ -61,12 +60,7 @@ protected function execute(InputInterface $input, OutputInterface $output): int

// TODO: verify namespace

$r = RunnerBuilder::create()
->withIO($this->io)
->withConfig($this->config)
->build($namespace);

$cwd = $r->run($this->resolvePackage($namespace, $url));
$cwd = runLocally(fn() => $this->resolvePackage($namespace, $url), $namespace);

if (! exists($cwd . '/mager.yaml')) {
throw new \InvalidArgumentException("Cant find 'mager.yaml' in '$cwd'");
Expand All @@ -76,11 +70,11 @@ protected function execute(InputInterface $input, OutputInterface $output): int
/** @var AppDefinition $appDefinition */
$appDefinition = $appDefinitionBuilder->build($cwd . '/mager.yaml');

if (($code = $r->run($this->deploy($namespace, $cwd, $appDefinition))) === Command::FAILURE) {
if (($code = runOnManager(fn() => $this->deploy($namespace, $cwd, $appDefinition), $namespace)) === Command::FAILURE) {
return $code;
}

$this->config->set("{$namespace}.apps.{$url}", true);
$this->config->set("{$namespace}.apps.{$appDefinition->name}", $url);
$this->config->save();

return $code;
Expand Down
8 changes: 1 addition & 7 deletions src/Command/BuildCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
namespace App\Command;

use App\Component\Config\Config;
use App\Component\TaskRunner\RunnerBuilder;
use Symfony\Component\Console\Attribute\AsCommand;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
Expand Down Expand Up @@ -97,11 +96,6 @@ protected function execute(InputInterface $input, OutputInterface $output): int
Assert::notEmpty($name, '--name must be a non-empty string');
Assert::notEmpty($config, "Namespace {$namespace} are not initialized, run mager namespace:add {$namespace}");

$r = RunnerBuilder::create()
->withIO($this->io)
->withConfig($this->config)
->build($namespace, local: true);

if (! exists($dockerfile)) {
$this->io->error('Dockerfile does not exist');

Expand All @@ -110,7 +104,7 @@ protected function execute(InputInterface $input, OutputInterface $output): int

$imageName = "{$namespace}-{$name}:{$version}";

return $r->run($this->buildAndSaveImage(
return runLocally(fn() => $this->buildAndSaveImage(
$namespace,
$dockerfile,
$imageName,
Expand Down
69 changes: 50 additions & 19 deletions src/Command/DeployCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@
use App\Component\Config\Definition\Service;
use App\Component\Config\DefinitionBuilder;
use App\Component\Config\ServiceDefinition;
use App\Component\TaskRunner\RunnerBuilder;
use App\Component\TaskRunner\TaskBuilder\DockerCreateService;
use App\Helper\CommandHelper;
use App\Helper\ConfigHelper;
Expand All @@ -32,6 +31,10 @@ final class DeployCommand extends Command
{
private SymfonyStyle $io;

private bool $isPreview = false;

private bool $isDev = false;

public function __construct(
private readonly Config $config,
private readonly DefinitionBuilder $definitionBuilder,
Expand All @@ -45,14 +48,20 @@ protected function configure(): void
'namespace',
InputArgument::OPTIONAL,
'Deploy service to servers that listed for given namespace',
'local',
);

$this->addOption(
'dev',
null,
InputOption::VALUE_NONE,
'Setup for mager for local development include proxy auto configuration',
'Deploy service to local namespace',
);

$this->addOption(
'preview',
null,
InputOption::VALUE_NONE,
'Deploy service to preview environment',
);
}

Expand All @@ -61,7 +70,19 @@ protected function execute(InputInterface $input, OutputInterface $output): int
$this->io = new SymfonyStyle($input, $output);

$namespace = $input->getArgument('namespace');
$override = $input->getOption('dev') ? 'dev' : 'prod';
$this->isDev = $input->getOption('dev') ?? false;
$this->isPreview = $input->getOption('preview') ?? false;

$override = 'prod';
if ($this->isPreview) {
Assert::eq($namespace, 'local', "Deploy preview require non-local namespace");
$override = 'preview';
}

if ($this->isDev) {
$namespace = 'local';
$override = 'dev';
}

$config = $this->config->get($namespace);

Expand All @@ -70,19 +91,29 @@ protected function execute(InputInterface $input, OutputInterface $output): int
/** @var ServiceDefinition $definition */
$definition = $this->definitionBuilder->build(override: $override);

$r = RunnerBuilder::create()
->withIO($this->io)
->withConfig($this->config)
->build($namespace);

$this->io->title('Checking Requirement');
if (! $r->run($this->ensureServerArePrepared($namespace))) {
if (! runOnManager(fn() => $this->ensureServerArePrepared($namespace), $namespace)) {
return Command::FAILURE;
}

$version = getenv('APP_VERSION');
$this->io->title('Building Image');

$version = getenv('VERSION');
$version = false === $version ? 'latest' : $version;

if ($this->isPreview && $version !== 'latest') {
$version = runLocally(function() {
// try to look github sha commit first
$version = getenv('GITHUB_SHA');
$version = $version !== false ? $version : yield 'git rev-parse HEAD';
return $version ?? 'latest';
}, throwError: false);
}

if ($version === 'latest') {
$this->io->warning('VERSION environment variable is not detected, using latest as image tag');
}

// Build target image
$build = new ArrayInput([
'command' => 'build',
Expand All @@ -99,7 +130,7 @@ protected function execute(InputInterface $input, OutputInterface $output): int
$this->getApplication()->doRun($build, $output);

$this->io->title('Transfer and Load Image');
$r->run(CommandHelper::transferAndLoadImage($namespace, $definition->name, $this->config->isLocal($namespace)));
runOnManager(fn() => CommandHelper::transferAndLoadImage($namespace, $definition->name, $this->config->isLocal($namespace)), $namespace);

$this->io->title('Deploying Service');
$isLocal = $this->config->get("{$namespace}.is_local");
Expand All @@ -109,37 +140,37 @@ protected function execute(InputInterface $input, OutputInterface $output): int
foreach ($definition->services as $service) {
$this->io->section("Executing Before Deploy Hooks {$service->name}");
foreach ($service->beforeDeploy as $job) {
$r->run($this->runJob(
runOnManager(fn() => $this->runJob(
job: $job,
namespace: $namespace,
imageName: $imageName,
serviceName: $service->name,
service: $service,
));
), $namespace);
}

if (null !== $service->proxy->rule && $isLocal) {
$r->run($this->setupTls($namespace, $service));
runLocally(fn() => $this->setupTls($namespace, $service));
}

$this->io->section("Deploying {$service->name}");
$r->run($this->deploy(
runOnManager(fn() => $this->deploy(
namespace: $namespace,
imageName: $imageName,
serviceName: $service->name,
service: $service,
isLocal: $isLocal,
));
), $namespace);

$this->io->section("Executing After Deploy Hooks {$service->name}");
foreach ($service->afterDeploy as $job) {
$r->run($this->runJob(
runOnManager(fn() => $this->runJob(
job: $job,
namespace: $namespace,
imageName: $imageName,
serviceName: $service->name,
service: $service,
));
), $namespace);
}
}

Expand Down
8 changes: 1 addition & 7 deletions src/Command/NamespaceDelCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
namespace App\Command;

use App\Component\Config\Config;
use App\Component\TaskRunner\RunnerBuilder;
use Symfony\Component\Console\Attribute\AsCommand;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputArgument;
Expand Down Expand Up @@ -43,14 +42,9 @@ protected function execute(InputInterface $input, OutputInterface $output): int
$config = $this->config->get($namespace);
Assert::notEmpty($config, "Namespace {$namespace} are not initialized, run mager namespace:add {$namespace}");

$r = RunnerBuilder::create()
->withIO($this->io)
->withConfig($this->config)
->build($namespace);

$this->io->title("Removing namespace {$namespace} and associated services");

return $r->run($this->removeAllAssociatedServices($namespace));
return runOnManager(fn() => $this->removeAllAssociatedServices($namespace), $namespace);
}

private function removeAllAssociatedServices(string $namespace): \Generator
Expand Down
12 changes: 3 additions & 9 deletions src/Command/PrepareCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@

use App\Component\Config\Config;
use App\Component\Config\Data\Server as ServerConfig;
use App\Component\TaskRunner\RunnerBuilder;
use App\Component\TaskRunner\TaskBuilder\DockerCreateService;
use App\Helper\CommandHelper;
use App\Helper\ConfigHelper;
Expand Down Expand Up @@ -58,19 +57,14 @@ protected function execute(InputInterface $input, OutputInterface $output): int
return Command::FAILURE;
}

$r = RunnerBuilder::create()
->withIO($this->io)
->withConfig($this->config)
->build($namespace);

$this->io->title('Preparing Docker Swarm');
$r->run($this->prepareDockerSwarm($serverConfig));
runOnManager(fn() => $this->prepareDockerSwarm($serverConfig), $namespace);

$this->io->title('Preparing Docker Swarm Network');
$r->run($this->prepareNetwork($namespace), throwError: false);
runOnManager(fn() => $this->prepareNetwork($namespace), $namespace);

$this->io->title('Installing Proxy');
$r->run($this->prepareProxy($namespace));
runOnManager(fn() => $this->prepareProxy($namespace), $namespace);

$this->io->success('Namespace Was Successfully Prepared');

Expand Down
Loading

0 comments on commit a40da03

Please sign in to comment.