getClient(); if (!$client->getIp()) { throw new BadRequestHttpException('IP is required'); } $partitionInfo = []; if ($partition) { $partitionInfo["numPartition"] = $partition->getPartitionNumber(); $partitionInfo["numDisk"] = $partition->getDiskNumber(); $partitionInfo["partitionCode"] = $partition->getPartitionCode(); $partitionInfo["filesystem"] = $partition->getFilesystem(); $partitionInfo["osName"] = $partition->getOperativeSystem()?->getName(); $image->setPartitionInfo(json_encode($partitionInfo)); } else { $partitionInfo = json_decode($image->getPartitionInfo(), true); } if ($image->getType() === 'monolithic') { $repository = $image->getClient()->getRepository(); $latestImageRepo = $this->entityManager->getRepository(ImageImageRepository::class)->findLatestVersionByImageAndRepository($image, $repository); $imageImageRepository = new ImageImageRepository(); $imageImageRepository->setName($image->getName().'_v'.($latestImageRepo ? $latestImageRepo->getVersion() + 1 : 1)); $imageImageRepository->setImage($image); $imageImageRepository->setRepository($repository); $imageImageRepository->setStatus(ImageStatus::IN_PROGRESS); $imageImageRepository->setVersion($latestImageRepo ? $latestImageRepo->getVersion() + 1 : 1); $imageImageRepository->setPartitionInfo(json_encode($partitionInfo)); $this->entityManager->persist($imageImageRepository); return $this->createMonolithicImage($imageImageRepository, $partitionInfo, $image, $repository, $client, $queue); } else { $repository = $image->getClient()->getRepository(); // Para imágenes Git, no necesitamos crear entidades en la base de datos // ya que los repositorios Git son datos externos return $this->createGitImage($image, $partitionInfo, $repository, $queue, $gitRepositoryName); } } /** * @throws TransportExceptionInterface * @throws ServerExceptionInterface * @throws RedirectionExceptionInterface * @throws ClientExceptionInterface */ public function createMonolithicImage( ImageImageRepository $imageImageRepository, array $partitionInfo, Image $image, ImageRepository $repository, ?Client $client = null, bool $queue = false ): JsonResponse { if (!isset($partitionInfo['numDisk'], $partitionInfo['numPartition'], $partitionInfo['partitionCode'], $partitionInfo['filesystem'])) { throw new BadRequestHttpException('Missing required partition information'); } $client = $client ?? $image->getClient(); if (!$client->getIp() || !$client->getToken()) { throw new BadRequestHttpException('Client IP or token is missing'); } $data = [ 'dsk' => (string) $partitionInfo['numDisk'], 'par' => (string) $partitionInfo['numPartition'], 'cpt' => null, 'idi' => $imageImageRepository->getUuid(), 'nci' => $image->getName().'_v'.$imageImageRepository->getVersion(), 'ipr' => $repository->getIp(), 'nfn' => 'CrearImagen', 'ids' => '0' ]; $partitionTypes = PartitionTypes::getPartitionTypes(); $partitionCode = $partitionInfo['partitionCode']; $cptKey = array_search($partitionCode, array_column($partitionTypes, 'name'), true); if ($cptKey !== false) { $keys = array_keys($partitionTypes); $partitionTypeCode = $keys[$cptKey]; $data['cpt'] = dechex($partitionTypeCode); } else { throw new BadRequestHttpException("Invalid partition code: {$partitionCode}"); } $this->logger->info('Creating image', ['image' => $image->getId()]); try { $response = $this->createRequest( method: 'POST', url: 'https://'.$client->getIp().':8000/opengnsys/CrearImagen', params: [ 'json' => $data, ], token: $client->getToken(), ); $this->logger->info('Creating image', ['image' => $imageImageRepository->getName(), 'repository' => $repository->getIp()]); if (isset($response['error']) && $response['code'] === Response::HTTP_INTERNAL_SERVER_ERROR) { if ($queue) { $inputData = [ 'method' => 'CrearImagen', 'type' => 'monolithic', 'client' => $client->getUuid(), 'image' => $image->getUuid(), 'partitionCode' => $partitionInfo['partitionCode'], 'partitionType' => $partitionInfo['filesystem'], 'repository' => $repository->getIp(), 'name' => $image->getName().'_v'.$imageImageRepository->getVersion(), ]; $this->createService->__invoke($client, CommandTypes::CREATE_IMAGE, TraceStatus::PENDING, null, $inputData); return new JsonResponse(data: [], status: Response::HTTP_OK); } throw new BadRequestHttpException('Error creating image: ' . ($response['message'] ?? 'Unknown error')); } if (!isset($response['job_id'])) { throw new BadRequestHttpException('No job ID received from server'); } $jobId = $response['job_id']; try { $client->setStatus(ClientStatus::BUSY); $imageImageRepository->setStatus(ImageStatus::IN_PROGRESS); $this->entityManager->persist($client); $this->entityManager->persist($imageImageRepository); $this->entityManager->flush(); $inputData = [ 'method' => 'CrearImagen', 'type' => 'monolithic', 'client' => $client->getUuid(), 'image' => $image->getUuid(), 'partitionCode' => $partitionInfo['partitionCode'], 'partitionType' => $partitionInfo['filesystem'], 'repository' => $repository->getIp(), 'name' => $image->getName().'_v'.$imageImageRepository->getVersion(), ]; $this->createService->__invoke( $image->getClient(), CommandTypes::CREATE_IMAGE, TraceStatus::IN_PROGRESS, $jobId, $inputData ); return new JsonResponse(data: $image, status: Response::HTTP_OK); } catch (Exception $e) { $client->setStatus(ClientStatus::OG_LIVE); $this->entityManager->persist($client); $this->entityManager->flush(); throw $e; } } catch (Exception $e) { $this->logger->error('Error in monolithic image creation process', [ 'repository' => $repository->getId(), 'error' => $e->getMessage(), 'trace' => $e->getTraceAsString() ]); return new JsonResponse( data: ['error' => $e->getMessage()], status: Response::HTTP_INTERNAL_SERVER_ERROR ); } } public function createGitImage( Image $image, array $partitionInfo, ImageRepository $repository, bool $queue = false, ?string $gitRepositoryName = null ): JsonResponse { if (!isset($partitionInfo['numDisk'], $partitionInfo['numPartition'], $partitionInfo['partitionCode'], $partitionInfo['filesystem'])) { throw new BadRequestHttpException('Missing required partition information'); } $client = $image->getClient(); if (!$client->getIp() || !$client->getToken()) { throw new BadRequestHttpException('Client IP or token is missing'); } try { $data = [ 'dsk' => (string) $partitionInfo['numDisk'], 'par' => (string) $partitionInfo['numPartition'], 'cpt' => null, 'idi' => $gitRepositoryName ?: $image->getUuid(), 'nci' => $gitRepositoryName ?: $image->getName(), 'ipr' => $repository->getIp(), 'nfn' => 'CrearImagenGit', 'tag' => '', 'ids' => '0' ]; $partitionTypes = PartitionTypes::getPartitionTypes(); $partitionCode = $partitionInfo['partitionCode']; $cptKey = array_search($partitionCode, array_column($partitionTypes, 'name'), true); if ($cptKey !== false) { $keys = array_keys($partitionTypes); $partitionTypeCode = $keys[$cptKey]; $data['cpt'] = dechex($partitionTypeCode); } else { throw new BadRequestHttpException("Invalid partition code: {$partitionCode}"); } //$this->sshKeyAction->__invoke($repository, $client); $response = $this->createRequest( method: 'POST', url: 'https://'.$client->getIp().':8000/opengnsys/CrearImagenGit', params: [ 'json' => $data, ], token: $client->getToken(), ); if (isset($response['error']) && $response['code'] === Response::HTTP_INTERNAL_SERVER_ERROR) { if ($queue) { $inputData = [ 'method' => 'CrearImagenGit', 'type' => 'git', 'client' => $client->getUuid(), 'image' => $image->getUuid(), 'partitionCode' => $partitionInfo['partitionCode'], 'partitionType' => $partitionInfo['filesystem'], 'repository' => $repository->getIp(), 'name' => $image->getName(), ]; $this->createService->__invoke($client, CommandTypes::CREATE_IMAGE_GIT, TraceStatus::PENDING, null, $inputData); return new JsonResponse(data: [], status: Response::HTTP_OK); } throw new BadRequestHttpException('Error creating image: ' . ($response['message'] ?? 'Unknown error')); } if (!isset($response['job_id'])) { throw new BadRequestHttpException('No job ID received from server'); } $jobId = $response['job_id']; try { $client->setStatus(ClientStatus::BUSY); $this->entityManager->persist($client); $this->entityManager->flush(); $inputData = [ 'method' => 'CrearImagenGit', 'type' => 'git', 'client' => $client->getUuid(), 'image' => $image->getUuid(), 'partitionCode' => $partitionInfo['partitionCode'], 'partitionType' => $partitionInfo['filesystem'], 'repository' => $repository->getIp(), 'name' => $image->getName(), ]; $this->createService->__invoke( $image->getClient(), CommandTypes::CREATE_IMAGE_GIT, TraceStatus::IN_PROGRESS, $jobId, $inputData ); return new JsonResponse(data: $image, status: Response::HTTP_OK); } catch (Exception $e) { $client->setStatus(ClientStatus::OG_LIVE); $this->entityManager->persist($client); $this->entityManager->flush(); throw $e; } } catch (Exception $e) { $this->logger->error('Error in git image creation process', [ 'repository' => $repository->getId(), 'error' => $e->getMessage(), 'trace' => $e->getTraceAsString() ]); return new JsonResponse( data: ['error' => $e->getMessage()], status: Response::HTTP_INTERNAL_SERVER_ERROR ); } } }