Merge pull request 'develop' (#52) from develop into main
ogcore-debian-package/pipeline/head This commit looks good Details
testing/ogcore-api/pipeline/head There was a failure building this commit Details

Reviewed-on: #52
pull/53/head^2
Manuel Aranda Rosales 2025-09-04 13:58:06 +02:00
commit daf6720f10
6 changed files with 191 additions and 70 deletions

View File

@ -5,7 +5,7 @@ declare(strict_types=1);
namespace App\Command;
use App\Controller\OgAgent\CreateImageAction;
use App\Controller\OgAgent\DeployImageAction;
use App\Controller\DeployImageAction;
use App\Controller\OgAgent\PartitionAssistantAction;
use App\Controller\OgAgent\RunScriptAction;
use App\Dto\Input\CommandExecuteInput;
@ -14,7 +14,6 @@ use App\Dto\Input\PartitionInput;
use App\Dto\Input\PartitionPostInput;
use App\Dto\Input\MultipleClientsInput;
use App\Dto\Input\BootClientsInput;
use App\Dto\Input\SoftwareInventoryPartitionInput;
use App\Dto\Output\ClientOutput;
use App\Dto\Output\PartitionOutput;
use App\Entity\Client;
@ -30,6 +29,7 @@ use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Style\SymfonyStyle;
use Psr\Log\LoggerInterface;
#[AsCommand(name: 'opengnsys:execute-pending-traces', description: 'Execute pending traces')]
class ExecutePendingTracesCommand extends Command
@ -43,6 +43,7 @@ class ExecutePendingTracesCommand extends Command
private readonly \App\Controller\OgAgent\RebootAction $rebootAction,
private readonly \App\Controller\OgAgent\PowerOffAction $powerOffAction,
private readonly \App\Controller\OgAgent\LoginAction $loginAction,
private readonly LoggerInterface $logger,
) {
parent::__construct();
}
@ -52,6 +53,8 @@ class ExecutePendingTracesCommand extends Command
$io = new SymfonyStyle($input, $output);
$startTime = microtime(true);
$this->logger->info('Executing pending traces command');
$traces = $this->entityManager->getRepository(Trace::class)
->createQueryBuilder('t')
->select('t')
@ -112,6 +115,12 @@ class ExecutePendingTracesCommand extends Command
$input = $trace->getInput() ?? [];
$client = $trace->getClient();
$this->logger->info('Executing trace', [
'command' => $command,
'input' => $input,
'client' => $client->getUuid()
]);
if (!$client) {
throw new \Exception("No client associated with trace");
}
@ -123,27 +132,59 @@ class ExecutePendingTracesCommand extends Command
try {
switch ($command) {
case CommandTypes::CREATE_IMAGE:
$this->logger->info('Executing create image trace', [
'input' => $input,
'client' => $client->getUuid()
]);
return $this->executeCreateImage($trace, $input);
case CommandTypes::DEPLOY_IMAGE:
$this->logger->info('Executing deploy image trace', [
'input' => $input,
'client' => $client->getUuid()
]);
return $this->executeDeployImage($trace, $input);
case CommandTypes::PARTITION_AND_FORMAT:
$this->logger->info('Executing partition and format trace', [
'input' => $input,
'client' => $client->getUuid()
]);
return $this->executePartitionAssistant($trace, $input);
case CommandTypes::RUN_SCRIPT:
$this->logger->info('Executing run script trace', [
'input' => $input,
'client' => $client->getUuid()
]);
return $this->executeRunScript($trace, $input);
case CommandTypes::POWER_ON:
$this->logger->info('Executing power on trace', [
'input' => $input,
'client' => $client->getUuid()
]);
return $this->executePowerOn($trace, $input);
case CommandTypes::REBOOT:
$this->logger->info('Executing reboot trace', [
'input' => $input,
'client' => $client->getUuid()
]);
return $this->executeReboot($trace, $input);
case CommandTypes::SHUTDOWN:
$this->logger->info('Executing shutdown trace', [
'input' => $input,
'client' => $client->getUuid()
]);
return $this->executeShutdown($trace, $input);
case CommandTypes::LOGIN:
$this->logger->info('Executing login trace', [
'input' => $input,
'client' => $client->getUuid()
]);
return $this->executeLogin($trace, $input);
@ -151,6 +192,12 @@ class ExecutePendingTracesCommand extends Command
throw new \Exception("Unsupported command type: $command");
}
} catch (\Exception $e) {
$this->logger->error('Error executing trace', [
'command' => $command,
'input' => $input,
'client' => $client->getUuid(),
'error' => $e->getMessage()
]);
$trace->setStatus(TraceStatus::FAILED);
$trace->setOutput($e->getMessage());
$trace->setFinishedAt(new \DateTime());
@ -214,6 +261,12 @@ class ExecutePendingTracesCommand extends Command
}
}
$this->logger->info('Creating image', [
'image' => $image,
'partition' => $partition,
'client' => $client->getUuid()
]);
try {
$response = $this->createImageAction->__invoke(
queue: false,
@ -259,22 +312,33 @@ class ExecutePendingTracesCommand extends Command
$deployInput->type = $input['type'] ?? 'monolithic';
$deployInput->diskNumber = $input['diskNumber'] ?? 1;
$deployInput->partitionNumber = $input['partitionNumber'] ?? 1;
$deployInput->mcastMode = $input['mcastMode'] ?? 'duplex';
$deployInput->mcastSpeed = $input['mcastSpeed'] ?? 100;
$deployInput->mcastPort = $input['mcastPort'] ?? 8000;
$deployInput->mcastIp = $input['mcastIp'] ?? '224.0.0.1';
$deployInput->maxClients = $input['maxClients'] ?? 10;
$deployInput->maxTime = $input['maxTime'] ?? 3600;
$deployInput->p2pMode = $input['p2pMode'] ?? 'seed';
$deployInput->p2pTime = $input['p2pTime'] ?? 300;
$deployInput->mcastMode = $input['mcastMode'] ?? null;
$deployInput->mcastSpeed = $input['mcastSpeed'] ?? null;
$deployInput->mcastPort = $input['mcastPort'] ?? null;
$deployInput->mcastIp = $input['mcastIp'] ?? null;
$deployInput->maxClients = $input['maxClients'] ?? null;
$deployInput->maxTime = $input['maxTime'] ?? null;
$deployInput->p2pMode = $input['p2pMode'] ?? null;
$deployInput->p2pTime = $input['p2pTime'] ?? null;
$deployInput->queue = $input['queue'] ?? false;
$deployInput->clients = [new ClientOutput($client)];
$jobId = $this->deployImageAction->__invoke(
imageImageRepository: $imageImageRepository,
input: $deployInput,
client: $client
);
$this->logger->info('Deploying image', [
'input' => $deployInput,
'client' => $client->getUuid()
]);
$trace->setJobId($jobId);
$response = $this->deployImageAction->__invoke($deployInput, $imageImageRepository, $trace);
$clientJobs = $response['data'];
$clientKey = '/clients/' . $client->getUuid();
$jobId = $clientJobs[$clientKey] ?? [];
$trace->setJobId($jobId['jobId']);
$trace->setStatus(TraceStatus::IN_PROGRESS);
$trace->setFinishedAt(new \DateTime());
$this->entityManager->persist($trace);
$this->entityManager->flush();
@ -304,6 +368,11 @@ class ExecutePendingTracesCommand extends Command
$partitionInput->partitions = $partitions;
$partitionInput->queue = false;
$this->logger->info('Executing partition assistant', [
'input' => $partitionInput,
'client' => $client->getUuid()
]);
try {
$response = $this->partitionAssistantAction->__invoke($partitionInput, $trace);
@ -335,6 +404,11 @@ class ExecutePendingTracesCommand extends Command
$commandExecuteInput->script = $input['script'];
$commandExecuteInput->queue = false;
$this->logger->info('Executing run script', [
'input' => $commandExecuteInput,
'client' => $client->getUuid()
]);
try {
$response = $this->runScriptAction->__invoke($commandExecuteInput, $trace);

View File

@ -117,31 +117,61 @@ class RunScheduledCommandTasksCommand extends Command
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
]);
$input = [
'imageImageRepository' => $scriptParameters['imageUuid']
];
if (isset($scriptParameters['method'])) {
$input['method'] = $scriptParameters['method'];
}
if (isset($scriptParameters['type'])) {
$input['type'] = $scriptParameters['type'];
}
if (isset($scriptParameters['diskNumber'])) {
$input['diskNumber'] = $scriptParameters['diskNumber'];
}
if (isset($scriptParameters['partitionNumber'])) {
$input['partitionNumber'] = $scriptParameters['partitionNumber'];
}
if (isset($scriptParameters['mcastMode'])) {
$input['mcastMode'] = $scriptParameters['mcastMode'];
}
if (isset($scriptParameters['mcastSpeed'])) {
$input['mcastSpeed'] = $scriptParameters['mcastSpeed'];
}
if (isset($scriptParameters['mcastPort'])) {
$input['mcastPort'] = $scriptParameters['mcastPort'];
}
if (isset($scriptParameters['mcastIp'])) {
$input['mcastIp'] = $scriptParameters['mcastIp'];
}
if (isset($scriptParameters['maxClients'])) {
$input['maxClients'] = $scriptParameters['maxClients'];
}
if (isset($scriptParameters['maxTime'])) {
$input['maxTime'] = $scriptParameters['maxTime'];
}
if (isset($scriptParameters['p2pMode'])) {
$input['p2pMode'] = $scriptParameters['p2pMode'];
}
if (isset($scriptParameters['p2pTime'])) {
$input['p2pTime'] = $scriptParameters['p2pTime'];
}
$trace->setInput($input);
break;
case 'create-image':
$trace->setCommand(CommandTypes::CREATE_IMAGE);
$trace->setInput([
'type' => $scriptParameters['type'],
'name' => $scriptParameters['imageName'],
'imageName' => $scriptParameters['imageName'],
'imageUuid' => $scriptParameters['imageUuid'] ?? null,
'diskNumber' => $scriptParameters['diskNumber'] ?? null,
'partitionNumber' => $scriptParameters['partitionNumber'] ?? null,
'gitRepositoryName' => $scriptParameters['gitRepositoryName'] ?? null
'gitRepositoryName' => $scriptParameters['gitRepositoryName'] ?? null,
'action' => $scriptParameters['action'] ?? 'create'
]);
break;

View File

@ -6,6 +6,7 @@ namespace App\Controller;
use ApiPlatform\Validator\ValidatorInterface;
use App\Dto\Input\DeployImageInput;
use App\Entity\Trace;
use App\Model\ImageStatus;
use App\Entity\ImageImageRepository;
use App\Model\CommandTypes;
@ -16,7 +17,6 @@ use Doctrine\ORM\EntityManagerInterface;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Attribute\Route;
use Symfony\Contracts\HttpClient\Exception\ClientExceptionInterface;
use Symfony\Contracts\HttpClient\Exception\RedirectionExceptionInterface;
use Symfony\Contracts\HttpClient\Exception\ServerExceptionInterface;
@ -40,7 +40,7 @@ class DeployImageAction extends AbstractController
* @throws ClientExceptionInterface
* @throws ServerExceptionInterface
*/
public function __invoke(DeployImageInput $input, ImageImageRepository $image): JsonResponse
public function __invoke(DeployImageInput $input, ImageImageRepository $image, ?Trace $trace = null): JsonResponse
{
if ($image->getStatus() !== ImageStatus::SUCCESS) {
throw new BadRequestHttpException('Image is not ready to be deployed');
@ -51,42 +51,42 @@ class DeployImageAction extends AbstractController
$clientJobs = [];
if ($input->type === 'monolithic') {
$clientJobs = $this->handleMonolithicDeployment($input, $image);
$clientJobs = $this->handleMonolithicDeployment($input, $image, $trace);
}
return new JsonResponse(data: $clientJobs, status: Response::HTTP_OK);
}
private function handleMonolithicDeployment(DeployImageInput $input, ImageImageRepository $image): array
private function handleMonolithicDeployment(DeployImageInput $input, ImageImageRepository $image, ?Trace $trace = null): array
{
$clientJobs = [];
switch ($input->method) {
case DeployMethodTypes::UNICAST:
case DeployMethodTypes::UNICAST_DIRECT:
$clientJobs = $this->handleUnicastDeployment($input, $image);
$clientJobs = $this->handleUnicastDeployment($input, $image, $trace);
break;
case DeployMethodTypes::MULTICAST_UFTP:
case DeployMethodTypes::MULTICAST_UFTP_DIRECT:
case DeployMethodTypes::MULTICAST_UDPCAST:
case DeployMethodTypes::MULTICAST_UDPCAST_DIRECT:
$clientJobs = $this->handleMulticastDeployment($input, $image);
$clientJobs = $this->handleMulticastDeployment($input, $image, $trace);
break;
case DeployMethodTypes::TORRENT:
$clientJobs = $this->handleTorrentDeployment($input, $image);
$clientJobs = $this->handleTorrentDeployment($input, $image, $trace);
break;
}
return $clientJobs;
}
private function handleUnicastDeployment(DeployImageInput $input, ImageImageRepository $image): array
private function handleUnicastDeployment(DeployImageInput $input, ImageImageRepository $image, ?Trace $trace = null): array
{
$clientJobs = [];
foreach ($input->clients as $client) {
$inputData = $this->createInputData($input, $image, $client->getEntity());
$jobId = $this->processDeployment($client->getEntity(), $input, $image, $inputData, DeployMethodTypes::UNICAST);
$jobId = $this->processDeployment($client->getEntity(), $input, $image, $inputData, DeployMethodTypes::UNICAST, $trace);
if ($jobId) {
$clientJobs[(string) '/clients/' . $client->getEntity()->getUuid()] = $jobId;
@ -96,7 +96,7 @@ class DeployImageAction extends AbstractController
return $clientJobs;
}
private function handleMulticastDeployment(DeployImageInput $input, ImageImageRepository $image): array
private function handleMulticastDeployment(DeployImageInput $input, ImageImageRepository $image, ?Trace $trace = null): array
{
$clientJobs = [];
@ -109,7 +109,7 @@ class DeployImageAction extends AbstractController
continue;
}
$jobId = $this->processDeployment($client->getEntity(), $input, $image, $inputData, DeployMethodTypes::MULTICAST);
$jobId = $this->processDeployment($client->getEntity(), $input, $image, $inputData, DeployMethodTypes::MULTICAST, $trace);
if ($jobId) {
$clientJobs[(string) '/clients/' . $client->getEntity()->getUuid()] = $jobId;
@ -119,7 +119,7 @@ class DeployImageAction extends AbstractController
return $clientJobs;
}
private function handleTorrentDeployment(DeployImageInput $input, ImageImageRepository $image): array
private function handleTorrentDeployment(DeployImageInput $input, ImageImageRepository $image, ?Trace $trace = null): array
{
$clientJobs = [];
@ -137,7 +137,7 @@ class DeployImageAction extends AbstractController
throw $e;
}
$jobId = $this->processDeployment($client->getEntity(), $input, $image, $inputData, DeployMethodTypes::TORRENT);
$jobId = $this->processDeployment($client->getEntity(), $input, $image, $inputData, DeployMethodTypes::TORRENT, $trace);
if ($jobId) {
$clientJobs[(string) '/clients/' . $client->getEntity()->getUuid()] = $jobId;
@ -147,18 +147,34 @@ class DeployImageAction extends AbstractController
return $clientJobs;
}
private function processDeployment($client, DeployImageInput $input, ImageImageRepository $image, array $inputData, string $deployType): ?string
private function processDeployment($client, DeployImageInput $input, ImageImageRepository $image, array $inputData, string $deployType, ?Trace $trace = null): ?string
{
$agentJobId = $this->deployImageOgAgentAction->__invoke($image, $input, $client, $deployType);
if (!$agentJobId) {
if ($input->queue) {
$this->createService->__invoke($client, CommandTypes::DEPLOY_IMAGE, TraceStatus::PENDING, null, $inputData);
if ($trace) {
$trace->setStatus(TraceStatus::PENDING);
$trace->setJobId(null);
$trace->setInput($inputData);
$this->entityManager->persist($trace);
$this->entityManager->flush();
} else {
$this->createService->__invoke($client, CommandTypes::DEPLOY_IMAGE, TraceStatus::PENDING, null, $inputData);
}
}
return null;
}
$this->createService->__invoke($client, CommandTypes::DEPLOY_IMAGE, TraceStatus::IN_PROGRESS, $agentJobId, $inputData);
if ($trace) {
$trace->setStatus(TraceStatus::IN_PROGRESS);
$trace->setJobId($agentJobId);
$trace->setInput($inputData);
$this->entityManager->persist($trace);
$this->entityManager->flush();
} else {
$this->createService->__invoke($client, CommandTypes::DEPLOY_IMAGE, TraceStatus::IN_PROGRESS, $agentJobId, $inputData);
}
return $agentJobId;
}

View File

@ -254,15 +254,14 @@ class CreateImageAction extends AbstractOgAgentController
try {
$data = [
'dsk' => (string) $partitionInfo['numDisk'],
'par' => (string) $partitionInfo['numPartition'],
'cpt' => null,
'disk' => (string) $partitionInfo['numDisk'],
'partition' => (string) $partitionInfo['numPartition'],
'idi' => $gitRepositoryName ?: $image->getUuid(),
'nci' => $gitRepositoryName ?: $image->getName(),
'ipr' => $repository->getIp(),
'image_name' => $gitRepositoryName ?: $image->getName(),
'repository' => $repository->getIp(),
'nfn' => 'CrearImagenGit',
'tag' => '',
'ids' => '0'
'ids' => '0',
'message' => 'creating git image',
];
$partitionTypes = PartitionTypes::getPartitionTypes();

View File

@ -46,16 +46,15 @@ class DeployGitImageAction extends AbstractOgAgentController
$repository = $client->getRepository();
$data = [
'dsk' => (string) $input->diskNumber,
'par' => (string) $input->partitionNumber,
'ifs' => "1",
'idi' => 1,
'nci' => $input->repositoryName,
'ipr' => $repository->getIp(),
'disk' => (string) $input->diskNumber,
'partition' => (string) $input->partitionNumber,
'idi' => $input->repositoryName,
'image_name' => $input->repositoryName,
'repository' => $repository->getIp(),
'nfn' => 'RestaurarImagenGit',
'ptc' => 'git',
'ids' => '0',
'ref' => $input->hexsha ?? $input->tag
'commit' => $input->hexsha ?? $input->tag,
'branch' => $input->branch
];
$url = 'https://'.$client->getIp().':8000/opengnsys/RestaurarImagenGit';

View File

@ -38,13 +38,16 @@ class UpdateGitImageAction extends AbstractOgAgentController
$repository = $client->getRepository();
$data = [
'dsk' => (string) $partition->getDiskNumber(),
'par' => (string) $partition->getPartitionNumber(),
'nci' => $input->gitRepository,
'ipr' => $repository->getIp(),
'msg' => 'updating git image',
'disk' => (string) $partition->getDiskNumber(),
'partition' => (string) $partition->getPartitionNumber(),
'idi' => $input->gitRepository,
'image_name' => $input->gitRepository,
'repository' => $repository->getIp(),
'message' => 'updating git image',
'nfn' => 'ModificarImagenGit',
'ids' => '0'
'ids' => '0',
'branch' => $input->destinationBranch,
'options' => $input->options ? 'force push' : null,
];
$url = 'https://'.$client->getIp().':8000/opengnsys/ModificarImagenGit';