139 lines
5.3 KiB
PHP
139 lines
5.3 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace App\Controller\OgAgent;
|
|
|
|
use App\Entity\Client;
|
|
use App\Entity\Command;
|
|
use App\Entity\Image;
|
|
use App\Entity\ImageImageRepository;
|
|
use App\Entity\ImageRepository;
|
|
use App\Entity\Partition;
|
|
use App\Entity\Trace;
|
|
use App\Model\ClientStatus;
|
|
use App\Model\CommandTypes;
|
|
use App\Model\ImageStatus;
|
|
use App\Model\PartitionTypes;
|
|
use App\Model\TraceStatus;
|
|
use App\Service\Trace\CreateService;
|
|
use Doctrine\ORM\EntityManagerInterface;
|
|
use Exception;
|
|
use Psr\Log\LoggerInterface;
|
|
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
|
|
use Symfony\Component\HttpFoundation\JsonResponse;
|
|
use Symfony\Component\HttpFoundation\Response;
|
|
use Symfony\Component\Routing\Attribute\Route;
|
|
use Symfony\Component\Validator\Exception\ValidatorException;
|
|
use Symfony\Contracts\HttpClient\Exception\ClientExceptionInterface;
|
|
use Symfony\Contracts\HttpClient\Exception\RedirectionExceptionInterface;
|
|
use Symfony\Contracts\HttpClient\Exception\ServerExceptionInterface;
|
|
use Symfony\Contracts\HttpClient\Exception\TransportExceptionInterface;
|
|
use Symfony\Contracts\HttpClient\HttpClientInterface;
|
|
|
|
class CreateImageAction extends AbstractController
|
|
{
|
|
public function __construct(
|
|
protected readonly EntityManagerInterface $entityManager,
|
|
protected readonly HttpClientInterface $httpClient,
|
|
protected readonly CreateService $createService,
|
|
protected readonly LoggerInterface $logger,
|
|
)
|
|
{
|
|
}
|
|
|
|
/**
|
|
* @throws TransportExceptionInterface
|
|
* @throws ServerExceptionInterface
|
|
* @throws RedirectionExceptionInterface
|
|
* @throws ClientExceptionInterface
|
|
*/
|
|
public function __invoke(Image $image, ?Partition $partition = null): JsonResponse
|
|
{
|
|
if (!$image->getClient()->getIp()) {
|
|
throw new ValidatorException('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);
|
|
}
|
|
|
|
$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);
|
|
|
|
$this->entityManager->persist($imageImageRepository);
|
|
|
|
$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 Exception("El tipo de partición '$partitionCode' no se encontró en la lista.");
|
|
}
|
|
|
|
try {
|
|
$this->logger->info('Creating image', ['image' => $image->getId()]);
|
|
$response = $this->httpClient->request('POST', 'https://'.$image->getClient()->getIp().':8000/opengnsys/CrearImagen', [
|
|
'verify_peer' => false,
|
|
'verify_host' => false,
|
|
'headers' => [
|
|
'Content-Type' => 'application/json',
|
|
],
|
|
'json' => $data,
|
|
]);
|
|
|
|
|
|
} catch (TransportExceptionInterface $e) {
|
|
$this->logger->error('Error creating image', ['image' => $image->getId(), 'error' => $e->getMessage()]);
|
|
return new JsonResponse(
|
|
data: ['error' => $e->getMessage()],
|
|
status: Response::HTTP_INTERNAL_SERVER_ERROR
|
|
);
|
|
}
|
|
|
|
$jobId = json_decode($response->getContent(), true)['job_id'];
|
|
|
|
$client = $image->getClient();
|
|
$client->setStatus(ClientStatus::BUSY);
|
|
$this->entityManager->persist($client);
|
|
$this->entityManager->flush();
|
|
|
|
$this->createService->__invoke($image->getClient(), CommandTypes::CREATE_IMAGE, TraceStatus::IN_PROGRESS, $jobId, []);
|
|
|
|
return new JsonResponse(data: $image, status: Response::HTTP_OK);
|
|
}
|
|
}
|