224 lines
9.1 KiB
PHP
224 lines
9.1 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace App\Command;
|
|
|
|
use App\Controller\OgAgent\CreateImageAction;
|
|
use App\Controller\OgAgent\DeployImageAction;
|
|
use App\Controller\OgAgent\PartitionAssistantAction;
|
|
use App\Controller\OgAgent\RunScriptAction;
|
|
use App\Dto\Input\CommandExecuteInput;
|
|
use App\Dto\Input\DeployImageInput;
|
|
use App\Dto\Input\PartitionInput;
|
|
use App\Dto\Input\PartitionPostInput;
|
|
use App\Dto\Output\ClientOutput;
|
|
use App\Entity\CommandTask;
|
|
use App\Entity\Image;
|
|
use App\Entity\ImageImageRepository;
|
|
use App\Entity\Partition;
|
|
use App\Entity\Trace;
|
|
use App\Model\ClientStatus;
|
|
use App\Model\CommandTypes;
|
|
use App\Model\TraceStatus;
|
|
use App\Repository\CommandTaskRepository;
|
|
use Doctrine\ORM\EntityManagerInterface;
|
|
use Symfony\Component\Console\Attribute\AsCommand;
|
|
use Symfony\Component\Console\Command\Command;
|
|
use Symfony\Component\Console\Input\InputInterface;
|
|
use Symfony\Component\Console\Output\OutputInterface;
|
|
use Symfony\Contracts\HttpClient\Exception\TransportExceptionInterface;
|
|
|
|
#[AsCommand(name: 'opengnsys:run-scheduled-command-tasks', description: 'Run scheduled command tasks')]
|
|
class RunScheduledCommandTasksCommand extends Command
|
|
{
|
|
public function __construct(
|
|
private readonly CommandTaskRepository $commandTaskRepository,
|
|
private readonly EntityManagerInterface $entityManager,
|
|
private readonly RunScriptAction $runScriptAction,
|
|
private readonly DeployImageAction $deployImageAction,
|
|
private readonly CreateImageAction $createImageAction,
|
|
private readonly PartitionAssistantAction $partitionAssistantAction,
|
|
)
|
|
{
|
|
parent::__construct();
|
|
}
|
|
|
|
/**
|
|
* @throws \Exception
|
|
* @throws TransportExceptionInterface
|
|
*/
|
|
protected function execute(InputInterface $input, OutputInterface $output): int
|
|
{
|
|
$now = new \DateTimeImmutable('now');
|
|
|
|
$tasks = $this->commandTaskRepository->findAll();
|
|
|
|
foreach ($tasks as $task) {
|
|
/** @var CommandTask $task */
|
|
$nextExecution = $task->getNextExecution();
|
|
|
|
if (!$nextExecution) {
|
|
continue;
|
|
}
|
|
|
|
$difference = $now->getTimestamp() - $nextExecution->getTimestamp();
|
|
|
|
$output->writeln("Now: " . $now->format('Y-m-d H:i:s T'));
|
|
$output->writeln("NextExecution: " . $nextExecution->format('Y-m-d H:i:s T'));
|
|
$output->writeln("Diferencia: $difference segundos para la tarea {$task->getName()}");
|
|
|
|
if (abs($difference) < 30) {
|
|
$output->writeln("Ejecutando tarea: " . $task->getName());
|
|
|
|
$scripts = $task->getCommandTaskScripts()->toArray();
|
|
usort($scripts, fn($a, $b) => $a->getExecutionOrder() <=> $b->getExecutionOrder());
|
|
|
|
foreach ($scripts as $script) {
|
|
$output->writeln(" - Creando traza para script de tipo {$script->getType()} con orden {$script->getExecutionOrder()}");
|
|
|
|
$this->createTraceForScript($script, $task, $output);
|
|
}
|
|
|
|
$task->setLastExecution(new \DateTimeImmutable('now'));
|
|
$task->setNextExecution($task->calculateNextExecutionDate());
|
|
|
|
$this->entityManager->persist($task);
|
|
}
|
|
}
|
|
|
|
$this->entityManager->flush();
|
|
return Command::SUCCESS;
|
|
}
|
|
|
|
private function createTraceForScript($script, CommandTask $task, OutputInterface $output): void
|
|
{
|
|
$scriptParameters = $script->getParameters();
|
|
|
|
if ($task->getScope() !== 'clients') {
|
|
$clients = $task->getOrganizationalUnit()?->getClients();
|
|
} else {
|
|
$clients = $task->getClients();
|
|
}
|
|
|
|
foreach ($clients as $client) {
|
|
$trace = new Trace();
|
|
$trace->setClient($client);
|
|
$trace->setStatus(TraceStatus::PENDING);
|
|
$trace->setExecutedAt(new \DateTime());
|
|
|
|
switch ($script->getType()) {
|
|
case 'run-script':
|
|
$trace->setCommand(CommandTypes::RUN_SCRIPT);
|
|
$trace->setInput([
|
|
'script' => $script->getContent()
|
|
]);
|
|
break;
|
|
|
|
case 'deploy-image':
|
|
$trace->setCommand(CommandTypes::DEPLOY_IMAGE);
|
|
$trace->setInput([
|
|
'imageImageRepository' => $scriptParameters['imageImageRepositoryUuid'],
|
|
'method' => $scriptParameters['method'] ?? 'unicast',
|
|
'type' => $scriptParameters['type'] ?? 'monolithic',
|
|
'diskNumber' => $scriptParameters['diskNumber'] ?? 1,
|
|
'partitionNumber' => $scriptParameters['partitionNumber'] ?? 1,
|
|
'mcastMode' => $scriptParameters['mcastMode'] ?? 'duplex',
|
|
'mcastSpeed' => $scriptParameters['mcastSpeed'] ?? 100,
|
|
'mcastPort' => $scriptParameters['mcastPort'] ?? 8000,
|
|
'mcastIp' => $scriptParameters['mcastIp'] ?? '224.0.0.1',
|
|
'maxClients' => $scriptParameters['maxClients'] ?? 10,
|
|
'maxTime' => $scriptParameters['maxTime'] ?? 3600,
|
|
'p2pMode' => $scriptParameters['p2pMode'] ?? 'seed',
|
|
'p2pTime' => $scriptParameters['p2pTime'] ?? 300
|
|
]);
|
|
break;
|
|
|
|
case 'create-image':
|
|
$trace->setCommand(CommandTypes::CREATE_IMAGE);
|
|
$trace->setInput([
|
|
'image' => $scriptParameters['imageUuid'],
|
|
'diskNumber' => $scriptParameters['diskNumber'] ?? null,
|
|
'partitionNumber' => $scriptParameters['partitionNumber'] ?? null,
|
|
'gitRepositoryName' => $scriptParameters['gitRepositoryName'] ?? null
|
|
]);
|
|
break;
|
|
|
|
case 'partition-assistant':
|
|
$trace->setCommand(CommandTypes::PARTITION_AND_FORMAT);
|
|
$trace->setInput($scriptParameters);
|
|
break;
|
|
|
|
default:
|
|
$output->writeln(" - Tipo de script no soportado: {$script->getType()}");
|
|
continue 2; // Salta al siguiente cliente
|
|
}
|
|
|
|
$this->entityManager->persist($trace);
|
|
$output->writeln(" - Traza creada para cliente {$client->getUuid()} con comando {$trace->getCommand()}");
|
|
}
|
|
}
|
|
|
|
|
|
private function executePartitionAssistant($script, CommandTask $task, OutputInterface $output): void
|
|
{
|
|
$scriptParameters = $script->getParameters();
|
|
|
|
$output->writeln(" - Debug: Parameters = " . ($scriptParameters ? json_encode($scriptParameters) : 'null'));
|
|
|
|
if (!$scriptParameters) {
|
|
$output->writeln(" - Error: Parámetros del script vacíos o nulos");
|
|
return;
|
|
}
|
|
|
|
if (!is_array($scriptParameters)) {
|
|
$output->writeln(" - Error: Los parámetros deben ser un array");
|
|
return;
|
|
}
|
|
|
|
foreach ($task->getOrganizationalUnit()?->getClients() as $client) {
|
|
$partitionInput = new PartitionPostInput();
|
|
$partitionInput->clients = [new ClientOutput($client)];
|
|
|
|
$partitions = [];
|
|
|
|
foreach ($scriptParameters as $partitionData) {
|
|
if (isset($partitionData['removed']) && $partitionData['removed']) {
|
|
continue;
|
|
}
|
|
|
|
if (!isset($partitionData['size']) || $partitionData['size'] <= 0) {
|
|
continue;
|
|
}
|
|
|
|
$partitionInputObj = new PartitionInput();
|
|
$partitionInputObj->diskNumber = $partitionData['diskNumber'] ?? 1;
|
|
$partitionInputObj->partitionNumber = $partitionData['partitionNumber'] ?? 1;
|
|
$partitionInputObj->partitionCode = $partitionData['partitionCode'] ?? 'LINUX';
|
|
$partitionInputObj->size = (float)($partitionData['size'] / 1024);
|
|
$partitionInputObj->filesystem = $partitionData['filesystem'] ?? 'EXT4';
|
|
$partitionInputObj->format = $partitionData['format'] ?? false;
|
|
$partitionInputObj->memoryUsage = $partitionData['memoryUsage'] ?? 0;
|
|
|
|
$partitions[] = $partitionInputObj;
|
|
}
|
|
|
|
if (empty($partitions)) {
|
|
$output->writeln(" - Warning: No hay particiones válidas para procesar");
|
|
continue;
|
|
}
|
|
|
|
$partitionInput->partitions = $partitions;
|
|
$partitionInput->queue = false;
|
|
|
|
try {
|
|
$response = $this->partitionAssistantAction->__invoke($partitionInput, null);
|
|
|
|
$output->writeln(" - Partition assistant iniciado para cliente {$client->getUuid()}");
|
|
} catch (\Exception $e) {
|
|
$output->writeln(" - Error en partition assistant para cliente {$client->getUuid()}: " . $e->getMessage());
|
|
}
|
|
}
|
|
}
|
|
}
|