From 177b95f1b63290d06f208963f8115c289dcbd142 Mon Sep 17 00:00:00 2001 From: Nicolas Arenas Date: Mon, 28 Jul 2025 12:46:26 +0200 Subject: [PATCH 1/5] cronjobs (#42) Reviewed-on: https://ognproject.evlt.uma.es/gitea/opengnsys/ogcore/pulls/42 --- .gitignore | 3 ++- etc/cron.d/opengnsys-check-clients | 4 +++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/.gitignore b/.gitignore index 0efa7f8..6e36675 100644 --- a/.gitignore +++ b/.gitignore @@ -7,6 +7,7 @@ /public/bundles/ /var/ /vendor/ +api/public/bundles/ ###< symfony/framework-bundle ### #phpstorm @@ -31,5 +32,5 @@ debian/ogcore debian/*.substvars debian/*.log debian/.debhelper/ - +debian/files diff --git a/etc/cron.d/opengnsys-check-clients b/etc/cron.d/opengnsys-check-clients index e762794..28f5e88 100644 --- a/etc/cron.d/opengnsys-check-clients +++ b/etc/cron.d/opengnsys-check-clients @@ -1 +1,3 @@ -*/5 * * * * opengnsys php -d memory_limit=512M /opt/opengnsys/ogcore/api/bin/console opengnsys:check-client-availability >> /opt/opengnsys/ogcore/api/var/log/cron.log 2>&1 +*/2 * * * * opengnsys php -d memory_limit=512M /opt/opengnsys/ogcore/api/bin/console opengnsys:check-client-availability>> /opt/opengnsys/ogcore/api/var/log/cron.log 2>&1 +*/1 * * * * opengnsys php -d memory_limit=512M /opt/opengnsys/ogcore/api/bin/console opengnsys:run-scheduled-command-tasks>> /opt/opengnsys/ogcore/api/var/log/cron.log 2>&1 +*/1 * * * * opengnsys php -d memory_limit=512M /opt/opengnsys/ogcore/api/bin/console opengnsys:execute-pending-traces>> /opt/opengnsys/ogcore/api/var/log/cron.log 2>&1 \ No newline at end of file From 82d5edb55b9e2ac08df34ea069a4f2692c53ee41 Mon Sep 17 00:00:00 2001 From: Manuel Aranda Date: Tue, 29 Jul 2025 12:22:34 +0200 Subject: [PATCH 2/5] refs #2540. Fixed bug when delete client --- CHANGELOG.md | 10 ++++++++++ src/Controller/OgDhcp/Subnet/DeleteHostAction.php | 2 +- src/State/Processor/ClientProcessor.php | 6 +++--- 3 files changed, 14 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 86fde15..29dc4b3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,14 @@ # Changelog +## [0.17.1] - 2025-07-29 +### Fixed +- Se ha corregido un bug que aparecia al borrar un cliente. Este error hacia que se borrara el cliente de la base de datos, pero no del DHCP ( en caso de que perteneciera a uno) y el fichero de arranque. + +--- +## [0.17.0] - 2025-07-20 +### Added +- Se ha aƱadido la funcionalidad para modificar imagenes de ogGit. + +--- ## [0.16.0] - 2025-06-27 ### Added - Se ha cambiado el html del menu para ser compatible con HTML5. diff --git a/src/Controller/OgDhcp/Subnet/DeleteHostAction.php b/src/Controller/OgDhcp/Subnet/DeleteHostAction.php index 0346ff7..0959f78 100644 --- a/src/Controller/OgDhcp/Subnet/DeleteHostAction.php +++ b/src/Controller/OgDhcp/Subnet/DeleteHostAction.php @@ -29,7 +29,7 @@ class DeleteHostAction extends AbstractOgDhcpController { $client = $this->entityManager->getRepository(Client::class)->findOneBy(['uuid' => $clientUuid]); - if (!$client || $client->getSubnet() !== $data) { + if (!$client) { throw new BadRequestHttpException('Client not found'); } diff --git a/src/State/Processor/ClientProcessor.php b/src/State/Processor/ClientProcessor.php index 528ce64..f7685a9 100644 --- a/src/State/Processor/ClientProcessor.php +++ b/src/State/Processor/ClientProcessor.php @@ -103,16 +103,16 @@ readonly class ClientProcessor implements ProcessorInterface private function processDelete($data, Operation $operation, array $uriVariables = [], array $context = []): null { $client = $this->clientRepository->findOneByUuid($uriVariables['uuid']); - $this->clientRepository->delete($client); if ($this->kernel->getEnvironment() !== 'test') { - if ($client->getSubnet()) { $this->deleteHostAction->__invoke($client->getSubnet(), $client->getUuid()); } - $this->deletePxeAction->__invoke($client->getUuid()); + $this->deletePxeAction->__invoke($client->getMac()); } + $this->clientRepository->delete($client); + return null; } } From bc80b3af7c9e1a35ac8dacd6929af5682a9096d5 Mon Sep 17 00:00:00 2001 From: Manuel Aranda Date: Mon, 4 Aug 2025 10:50:11 +0200 Subject: [PATCH 3/5] refs #2591. new response. Added job_id --- src/Controller/DeployGitImageAction.php | 22 +++++-- src/Controller/DeployImageAction.php | 60 ++++++++++++++----- src/Controller/OgAgent/CreateImageAction.php | 4 +- .../OgAgent/PartitionAssistantAction.php | 18 +++++- src/Controller/OgAgent/RunScriptAction.php | 4 ++ src/State/Processor/ImageProcessor.php | 12 +++- src/State/Processor/PartitionProcessor.php | 8 ++- 7 files changed, 101 insertions(+), 27 deletions(-) diff --git a/src/Controller/DeployGitImageAction.php b/src/Controller/DeployGitImageAction.php index 62e1f16..73744f1 100644 --- a/src/Controller/DeployGitImageAction.php +++ b/src/Controller/DeployGitImageAction.php @@ -45,20 +45,28 @@ class DeployGitImageAction extends AbstractController { $this->validator->validate($input); - $this->handleGitDeployment($input); + $clientJobs = $this->handleGitDeployment($input); - return new JsonResponse(data: [], status: Response::HTTP_OK); + return new JsonResponse(data: $clientJobs, status: Response::HTTP_OK); } - private function handleGitDeployment(DeployGitImageInput $input): void + private function handleGitDeployment(DeployGitImageInput $input): array { + $clientJobs = []; + foreach ($input->clients as $client) { $inputData = $this->createInputData($input, $client->getEntity()); - $this->processDeployment($client->getEntity(), $input, $inputData, DeployMethodTypes::GIT); + $jobId = $this->processDeployment($client->getEntity(), $input, $inputData, DeployMethodTypes::GIT); + + if ($jobId) { + $clientJobs[(string) '/clients/' . $client->getEntity()->getUuid()] = $jobId; + } } + + return $clientJobs; } - private function processDeployment($client, DeployGitImageInput $input, array $inputData, string $deployType): void + private function processDeployment($client, DeployGitImageInput $input, array $inputData, string $deployType): ?string { $agentJobId = $this->deployGitImageOgAgentAction->__invoke($input, $client); @@ -66,10 +74,12 @@ class DeployGitImageAction extends AbstractController if ($input->queue) { $this->createService->__invoke($client, CommandTypes::DEPLOY_IMAGE, TraceStatus::PENDING, null, $inputData); } - return; + return null; } $this->createService->__invoke($client, CommandTypes::DEPLOY_IMAGE, TraceStatus::IN_PROGRESS, $agentJobId, $inputData); + + return $agentJobId; } private function createInputData(DeployGitImageInput $input, $client): array diff --git a/src/Controller/DeployImageAction.php b/src/Controller/DeployImageAction.php index 2a6ef6b..4ca8fc1 100644 --- a/src/Controller/DeployImageAction.php +++ b/src/Controller/DeployImageAction.php @@ -47,42 +47,58 @@ class DeployImageAction extends AbstractController { $this->validator->validate($input); + $clientJobs = []; + if ($input->type === 'monolithic') { - $this->handleMonolithicDeployment($input, $image); + $clientJobs = $this->handleMonolithicDeployment($input, $image); } - return new JsonResponse(data: [], status: Response::HTTP_OK); + return new JsonResponse(data: $clientJobs, status: Response::HTTP_OK); } - private function handleMonolithicDeployment(DeployImageInput $input, ImageImageRepository $image): void + private function handleMonolithicDeployment(DeployImageInput $input, ImageImageRepository $image): array { + $clientJobs = []; + switch ($input->method) { case DeployMethodTypes::UNICAST: case DeployMethodTypes::UNICAST_DIRECT: - $this->handleUnicastDeployment($input, $image); + $clientJobs = $this->handleUnicastDeployment($input, $image); break; case DeployMethodTypes::MULTICAST_UFTP: case DeployMethodTypes::MULTICAST_UFTP_DIRECT: case DeployMethodTypes::MULTICAST_UDPCAST: case DeployMethodTypes::MULTICAST_UDPCAST_DIRECT: - $this->handleMulticastDeployment($input, $image); + $clientJobs = $this->handleMulticastDeployment($input, $image); break; case DeployMethodTypes::TORRENT: - $this->handleTorrentDeployment($input, $image); + $clientJobs = $this->handleTorrentDeployment($input, $image); break; } + + return $clientJobs; } - private function handleUnicastDeployment(DeployImageInput $input, ImageImageRepository $image): void + private function handleUnicastDeployment(DeployImageInput $input, ImageImageRepository $image): array { + $clientJobs = []; + foreach ($input->clients as $client) { $inputData = $this->createInputData($input, $image, $client->getEntity()); - $this->processDeployment($client->getEntity(), $input, $image, $inputData, DeployMethodTypes::UNICAST); + $jobId = $this->processDeployment($client->getEntity(), $input, $image, $inputData, DeployMethodTypes::UNICAST); + + if ($jobId) { + $clientJobs[(string) '/clients/' . $client->getEntity()->getUuid()] = $jobId; + } } + + return $clientJobs; } - private function handleMulticastDeployment(DeployImageInput $input, ImageImageRepository $image): void + private function handleMulticastDeployment(DeployImageInput $input, ImageImageRepository $image): array { + $clientJobs = []; + foreach ($input->clients as $client) { $inputData = $this->createMulticastInputData($input, $image, $client->getEntity()); @@ -92,12 +108,20 @@ class DeployImageAction extends AbstractController continue; } - $this->processDeployment($client->getEntity(), $input, $image, $inputData, DeployMethodTypes::MULTICAST); + $jobId = $this->processDeployment($client->getEntity(), $input, $image, $inputData, DeployMethodTypes::MULTICAST); + + if ($jobId) { + $clientJobs[(string) '/clients/' . $client->getEntity()->getUuid()] = $jobId; + } } + + return $clientJobs; } - private function handleTorrentDeployment(DeployImageInput $input, ImageImageRepository $image): void + private function handleTorrentDeployment(DeployImageInput $input, ImageImageRepository $image): array { + $clientJobs = []; + foreach ($input->clients as $client) { $inputData = $this->createTorrentInputData($input, $image, $client->getEntity()); @@ -112,11 +136,17 @@ class DeployImageAction extends AbstractController throw $e; } - $this->processDeployment($client->getEntity(), $input, $image, $inputData, DeployMethodTypes::TORRENT); + $jobId = $this->processDeployment($client->getEntity(), $input, $image, $inputData, DeployMethodTypes::TORRENT); + + if ($jobId) { + $clientJobs[(string) '/clients/' . $client->getEntity()->getUuid()] = $jobId; + } } + + return $clientJobs; } - private function processDeployment($client, DeployImageInput $input, ImageImageRepository $image, array $inputData, string $deployType): void + private function processDeployment($client, DeployImageInput $input, ImageImageRepository $image, array $inputData, string $deployType): ?string { $agentJobId = $this->deployImageOgAgentAction->__invoke($image, $input, $client, $deployType); @@ -124,10 +154,12 @@ class DeployImageAction extends AbstractController if ($input->queue) { $this->createService->__invoke($client, CommandTypes::DEPLOY_IMAGE, TraceStatus::PENDING, null, $inputData); } - return; + return null; } $this->createService->__invoke($client, CommandTypes::DEPLOY_IMAGE, TraceStatus::IN_PROGRESS, $agentJobId, $inputData); + + return $agentJobId; } private function createInputData(DeployImageInput $input, ImageImageRepository $image, $client): array diff --git a/src/Controller/OgAgent/CreateImageAction.php b/src/Controller/OgAgent/CreateImageAction.php index 32b96a6..71149db 100644 --- a/src/Controller/OgAgent/CreateImageAction.php +++ b/src/Controller/OgAgent/CreateImageAction.php @@ -202,7 +202,7 @@ class CreateImageAction extends AbstractOgAgentController $inputData ); - return new JsonResponse(data: $image, status: Response::HTTP_OK); + return new JsonResponse(data: ['/clients/' . $client->getUuid() => $jobId], status: Response::HTTP_OK); } catch (Exception $e) { $client->setStatus(ClientStatus::OG_LIVE); $this->entityManager->persist($client); @@ -327,7 +327,7 @@ class CreateImageAction extends AbstractOgAgentController $inputData ); - return new JsonResponse(data: $image, status: Response::HTTP_OK); + return new JsonResponse(data: ['/clients/' . $client->getUuid() => $jobId], status: Response::HTTP_OK); } catch (Exception $e) { $client->setStatus(ClientStatus::OG_LIVE); $this->entityManager->persist($client); diff --git a/src/Controller/OgAgent/PartitionAssistantAction.php b/src/Controller/OgAgent/PartitionAssistantAction.php index 8d54721..0c4e288 100644 --- a/src/Controller/OgAgent/PartitionAssistantAction.php +++ b/src/Controller/OgAgent/PartitionAssistantAction.php @@ -45,6 +45,8 @@ class PartitionAssistantAction extends AbstractOgAgentController throw new BadRequestHttpException('Partitions is required'); } + $clientJobs = []; + foreach ($input->clients as $clientInput) { /** @var Client $client */ $client = $clientInput->getEntity(); @@ -125,10 +127,24 @@ class PartitionAssistantAction extends AbstractOgAgentController $this->entityManager->persist($client); $this->entityManager->flush(); +<<<<<<< Updated upstream $this->createService->__invoke($client, CommandTypes::PARTITION_AND_FORMAT, TraceStatus::IN_PROGRESS, $jobId, $data); +======= + if ($existingTrace) { + $existingTrace->setStatus(TraceStatus::IN_PROGRESS); + $existingTrace->setJobId($jobId); + $existingTrace->setInput($data); + $this->entityManager->persist($existingTrace); + $this->entityManager->flush(); + } else { + $this->createService->__invoke($client, CommandTypes::PARTITION_AND_FORMAT, TraceStatus::IN_PROGRESS, $jobId, $data); + } + + $clientJobs['/clients/' . $client->getUuid()] = $jobId; +>>>>>>> Stashed changes } } - return new JsonResponse(data: [], status: Response::HTTP_OK); + return new JsonResponse(data: $clientJobs, status: Response::HTTP_OK); } } diff --git a/src/Controller/OgAgent/RunScriptAction.php b/src/Controller/OgAgent/RunScriptAction.php index 16d95ee..af548f4 100644 --- a/src/Controller/OgAgent/RunScriptAction.php +++ b/src/Controller/OgAgent/RunScriptAction.php @@ -73,6 +73,10 @@ class RunScriptAction extends AbstractOgAgentController $this->logger->info('Powering off client', ['client' => $client->getId()]); $jobId = $response['job_id']; +<<<<<<< Updated upstream +======= + $clientJobs[(string) '/clients/' . $client->getUuid()] = $jobId; +>>>>>>> Stashed changes $this->entityManager->persist($client); $this->entityManager->flush(); diff --git a/src/State/Processor/ImageProcessor.php b/src/State/Processor/ImageProcessor.php index 24c94e2..a042009 100644 --- a/src/State/Processor/ImageProcessor.php +++ b/src/State/Processor/ImageProcessor.php @@ -22,6 +22,7 @@ use Symfony\Component\HttpKernel\KernelInterface; use Symfony\Contracts\HttpClient\Exception\TransportExceptionInterface; use Symfony\Component\HttpFoundation\JsonResponse; use Psr\Log\LoggerInterface; +use Symfony\Component\HttpFoundation\Response; readonly class ImageProcessor implements ProcessorInterface { @@ -39,7 +40,7 @@ readonly class ImageProcessor implements ProcessorInterface * @throws \Exception * @throws TransportExceptionInterface */ - public function process(mixed $data, Operation $operation, array $uriVariables = [], array $context = []): ImageOutput|null + public function process(mixed $data, Operation $operation, array $uriVariables = [], array $context = []): ImageOutput|null|JsonResponse { switch ($operation){ case $operation instanceof Post: @@ -55,7 +56,7 @@ readonly class ImageProcessor implements ProcessorInterface * @throws \Exception * @throws TransportExceptionInterface */ - private function processCreateOrUpdate($data, Operation $operation, array $uriVariables = [], array $context = []): ImageOutput + private function processCreateOrUpdate($data, Operation $operation, array $uriVariables = [], array $context = []): JsonResponse { if (!($data instanceof ImageInput)) { throw new \Exception(sprintf('data is not instance of %s', ImageInput::class)); @@ -87,7 +88,12 @@ readonly class ImageProcessor implements ProcessorInterface throw new \Exception($content['error'] ?? 'Error creating image'); } - return new ImageOutput($data->selectedImage?->getEntity() ?? $image); + if ($response instanceof JsonResponse && $response->getStatusCode() === 200) { + $jobContent = json_decode($response->getContent(), true); + return new JsonResponse(data: $jobContent, status: Response::HTTP_OK); + } + + return new JsonResponse(data: ['/clients/' . $image->getClient()->getUuid() => ['headers' => []]], status: Response::HTTP_OK); } catch (\Exception $e) { $this->logger->error('Error processing image creation/update', [ 'error' => $e->getMessage(), diff --git a/src/State/Processor/PartitionProcessor.php b/src/State/Processor/PartitionProcessor.php index 00e67a5..583061e 100644 --- a/src/State/Processor/PartitionProcessor.php +++ b/src/State/Processor/PartitionProcessor.php @@ -74,7 +74,13 @@ readonly class PartitionProcessor implements ProcessorInterface //$this->partitionRepository->save($entity); } - $this->partitionAssistantAction->__invoke($data); + $response = $this->partitionAssistantAction->__invoke($data); + + // Si hay una respuesta exitosa, devolvemos el contenido del job ID + if ($response instanceof JsonResponse && $response->getStatusCode() === 200) { + $jobContent = json_decode($response->getContent(), true); + return new JsonResponse(data: $jobContent, status: Response::HTTP_OK); + } return new JsonResponse('OK', Response::HTTP_NO_CONTENT); } From 49d09e1952dd251fcacd3126553d460943d4036c Mon Sep 17 00:00:00 2001 From: Manuel Aranda Date: Mon, 4 Aug 2025 10:51:22 +0200 Subject: [PATCH 4/5] refs #2591. new response. Added job_id --- CHANGELOG.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 29dc4b3..aa29024 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,9 @@ # Changelog +## [0.17.2] - 2025-08-04 +## Improved +- Se ha cambiado la respuesta de algunos endpoints que llaman al ogAgent. Ahora devuelve el job_id asociado a la traza. + +--- ## [0.17.1] - 2025-07-29 ### Fixed - Se ha corregido un bug que aparecia al borrar un cliente. Este error hacia que se borrara el cliente de la base de datos, pero no del DHCP ( en caso de que perteneciera a uno) y el fichero de arranque. From 3c78984217f0839382a70a8220e9a0cbfd73dd1b Mon Sep 17 00:00:00 2001 From: Manuel Aranda Date: Mon, 4 Aug 2025 11:00:29 +0200 Subject: [PATCH 5/5] refs #2591. new response. Added job_id --- src/Controller/OgAgent/PartitionAssistantAction.php | 12 ------------ src/Controller/OgAgent/RunScriptAction.php | 8 ++++---- 2 files changed, 4 insertions(+), 16 deletions(-) diff --git a/src/Controller/OgAgent/PartitionAssistantAction.php b/src/Controller/OgAgent/PartitionAssistantAction.php index 0c4e288..1ce5c61 100644 --- a/src/Controller/OgAgent/PartitionAssistantAction.php +++ b/src/Controller/OgAgent/PartitionAssistantAction.php @@ -127,21 +127,9 @@ class PartitionAssistantAction extends AbstractOgAgentController $this->entityManager->persist($client); $this->entityManager->flush(); -<<<<<<< Updated upstream $this->createService->__invoke($client, CommandTypes::PARTITION_AND_FORMAT, TraceStatus::IN_PROGRESS, $jobId, $data); -======= - if ($existingTrace) { - $existingTrace->setStatus(TraceStatus::IN_PROGRESS); - $existingTrace->setJobId($jobId); - $existingTrace->setInput($data); - $this->entityManager->persist($existingTrace); - $this->entityManager->flush(); - } else { - $this->createService->__invoke($client, CommandTypes::PARTITION_AND_FORMAT, TraceStatus::IN_PROGRESS, $jobId, $data); - } $clientJobs['/clients/' . $client->getUuid()] = $jobId; ->>>>>>> Stashed changes } } diff --git a/src/Controller/OgAgent/RunScriptAction.php b/src/Controller/OgAgent/RunScriptAction.php index af548f4..45b79d3 100644 --- a/src/Controller/OgAgent/RunScriptAction.php +++ b/src/Controller/OgAgent/RunScriptAction.php @@ -32,6 +32,8 @@ class RunScriptAction extends AbstractOgAgentController */ public function __invoke(CommandExecuteInput $input): JsonResponse { + $clientJobs = []; + /** @var Client $clientEntity */ foreach ($input->clients as $clientEntity) { /** @var Client $client */ @@ -73,10 +75,8 @@ class RunScriptAction extends AbstractOgAgentController $this->logger->info('Powering off client', ['client' => $client->getId()]); $jobId = $response['job_id']; -<<<<<<< Updated upstream -======= + $clientJobs[(string) '/clients/' . $client->getUuid()] = $jobId; ->>>>>>> Stashed changes $this->entityManager->persist($client); $this->entityManager->flush(); @@ -88,6 +88,6 @@ class RunScriptAction extends AbstractOgAgentController $this->createService->__invoke($client, CommandTypes::RUN_SCRIPT, TraceStatus::IN_PROGRESS, $jobId, $inputData); } - return new JsonResponse(data: [], status: Response::HTTP_OK); + return new JsonResponse(data: $clientJobs, status: Response::HTTP_OK); } } \ No newline at end of file