pull/49/head
parent
b5cd1b49ff
commit
20b9ffdfa1
|
@ -34,10 +34,26 @@ class BackupImageAction extends AbstractOgRepositoryController
|
|||
$image = $imageImageRepository->getImage();
|
||||
$repository = $imageImageRepository->getRepository();
|
||||
|
||||
$this->validateImageName($image);
|
||||
$this->logger->info('Create backup image', ['image' => $image->getName()]);
|
||||
|
||||
$content = $this->createBackupRequest($input, $imageImageRepository, $repository);
|
||||
$this->handleBackupResponse($content);
|
||||
|
||||
$this->processBackupSuccess($input, $image, $repository, $imageImageRepository, $content);
|
||||
|
||||
return new JsonResponse(data: $content, status: Response::HTTP_OK);
|
||||
}
|
||||
|
||||
private function validateImageName(Image $image): void
|
||||
{
|
||||
if (!$image->getName()) {
|
||||
throw new BadRequestHttpException('Name is required');
|
||||
}
|
||||
}
|
||||
|
||||
private function createBackupRequest(BackupImageInput $input, ImageImageRepository $imageImageRepository, ImageRepository $repository): array
|
||||
{
|
||||
$params = [
|
||||
'json' => [
|
||||
'ID_img' => $imageImageRepository->getImageFullsum(),
|
||||
|
@ -48,16 +64,85 @@ class BackupImageAction extends AbstractOgRepositoryController
|
|||
]
|
||||
];
|
||||
|
||||
$this->logger->info('Create backup image', ['image' => $image->getName()]);
|
||||
return $this->createRequest('PUT', 'http://'.$repository->getIp().':8006/ogrepository/v1/repo/images', $params);
|
||||
}
|
||||
|
||||
$repository = $imageImageRepository->getRepository();
|
||||
|
||||
$content = $this->createRequest('PUT', 'http://'.$repository->getIp().':8006/ogrepository/v1/repo/images', $params);
|
||||
|
||||
if (isset($content['error']) && $content['code'] === Response::HTTP_INTERNAL_SERVER_ERROR ) {
|
||||
throw new BadRequestHttpException('Error backing up image: ' . $content['error'] . ' - ' . $content['details']);
|
||||
private function handleBackupResponse(array $content): void
|
||||
{
|
||||
if (!isset($content['error'])) {
|
||||
return;
|
||||
}
|
||||
|
||||
$errorMessage = $this->extractErrorMessage($content);
|
||||
$errorCode = $content['code'] ?? Response::HTTP_BAD_REQUEST;
|
||||
|
||||
$this->throwAppropriateException($errorCode, $errorMessage);
|
||||
}
|
||||
|
||||
private function extractErrorMessage(array $content): string
|
||||
{
|
||||
$errorMessage = $content['error'];
|
||||
$errorDetails = $content['details'] ?? null;
|
||||
|
||||
if (!$errorDetails) {
|
||||
return $errorMessage;
|
||||
}
|
||||
|
||||
$extractedMessage = $this->extractMessageFromDetails($errorDetails);
|
||||
|
||||
return $extractedMessage ?: $errorMessage;
|
||||
}
|
||||
|
||||
private function extractMessageFromDetails($errorDetails): ?string
|
||||
{
|
||||
if (is_array($errorDetails)) {
|
||||
return $errorDetails['details'] ?? $errorDetails['message'] ?? $errorDetails['error'] ?? null;
|
||||
}
|
||||
|
||||
if (is_string($errorDetails)) {
|
||||
$parsed = $this->parseJsonString($errorDetails);
|
||||
if ($parsed !== null) {
|
||||
return $parsed['details'] ?? $parsed['message'] ?? $parsed['error'] ?? null;
|
||||
}
|
||||
|
||||
return !empty($errorDetails) ? $errorDetails : null;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private function parseJsonString(string $jsonString): ?array
|
||||
{
|
||||
$cleanJson = trim($jsonString, " \t\n\r\0\x0B");
|
||||
$decoded = json_decode($cleanJson, true);
|
||||
|
||||
return (json_last_error() === JSON_ERROR_NONE && is_array($decoded)) ? $decoded : null;
|
||||
}
|
||||
|
||||
private function throwAppropriateException(int $errorCode, string $errorMessage): void
|
||||
{
|
||||
if ($errorCode === Response::HTTP_INTERNAL_SERVER_ERROR) {
|
||||
throw new BadRequestHttpException('Error backing up image: ' . $errorMessage);
|
||||
}
|
||||
|
||||
if ($errorCode >= 400 && $errorCode < 500) {
|
||||
throw new BadRequestHttpException($errorMessage);
|
||||
}
|
||||
|
||||
if ($errorCode >= 500) {
|
||||
throw new BadRequestHttpException('Error backing up image: ' . $errorMessage);
|
||||
}
|
||||
|
||||
throw new BadRequestHttpException($errorMessage);
|
||||
}
|
||||
|
||||
private function processBackupSuccess(
|
||||
BackupImageInput $input,
|
||||
Image $image,
|
||||
ImageRepository $repository,
|
||||
ImageImageRepository $imageImageRepository,
|
||||
array $content
|
||||
): void {
|
||||
$inputData = [
|
||||
'imageName' => $image->getName(),
|
||||
'repositoryUuid' => $repository->getUuid(),
|
||||
|
@ -67,13 +152,16 @@ class BackupImageAction extends AbstractOgRepositoryController
|
|||
'remote_path' => $input->remotePath
|
||||
];
|
||||
|
||||
$this->createService->__invoke($image->getClient(), CommandTypes::BACKUP_IMAGE, TraceStatus::IN_PROGRESS, $content['job_id'], $inputData);
|
||||
$this->createService->__invoke(
|
||||
$image->getClient(),
|
||||
CommandTypes::BACKUP_IMAGE,
|
||||
TraceStatus::IN_PROGRESS,
|
||||
$content['job_id'],
|
||||
$inputData
|
||||
);
|
||||
|
||||
$imageImageRepository->setStatus(ImageStatus::BACKUP);
|
||||
$this->entityManager->persist($imageImageRepository);
|
||||
$this->entityManager->flush();
|
||||
|
||||
|
||||
return new JsonResponse(data: $content, status: Response::HTTP_OK);
|
||||
}
|
||||
}
|
|
@ -19,6 +19,7 @@ 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\Component\HttpKernel\Exception\HttpException;
|
||||
|
||||
#[AsController]
|
||||
class ImportAction extends AbstractOgRepositoryController
|
||||
|
@ -30,20 +31,52 @@ class ImportAction extends AbstractOgRepositoryController
|
|||
* @throws ClientExceptionInterface
|
||||
*/
|
||||
public function __invoke(ImportImageRepositoryInput $input, ImageRepository $repository): JsonResponse
|
||||
{
|
||||
$this->validateRepositoryStatus($repository);
|
||||
|
||||
$image = $input->name;
|
||||
$imageEntity = $this->getOrCreateImageEntity($image);
|
||||
$this->validateImageNotExistsInRepository($imageEntity, $repository);
|
||||
|
||||
$this->logger->info('Creating aux files', ['image' => $image]);
|
||||
|
||||
$content = $this->createTorrentSumRequest($repository, $image);
|
||||
$this->handleTorrentSumResponse($content);
|
||||
|
||||
$imageImageRepositoryEntity = $this->createImageImageRepositoryEntity($imageEntity, $repository, $image);
|
||||
$this->entityManager->persist($imageImageRepositoryEntity);
|
||||
$this->entityManager->flush();
|
||||
|
||||
$this->createService->__invoke(
|
||||
null,
|
||||
CommandTypes::CREATE_IMAGE_AUX_FILE,
|
||||
TraceStatus::IN_PROGRESS,
|
||||
$content['job_id'],
|
||||
[
|
||||
'imageName' => $image,
|
||||
'imageImageRepositoryUuid' => $imageImageRepositoryEntity->getUuid(),
|
||||
]
|
||||
);
|
||||
|
||||
return new JsonResponse(data: [], status: Response::HTTP_OK);
|
||||
}
|
||||
|
||||
private function validateRepositoryStatus(ImageRepository $repository): void
|
||||
{
|
||||
$content = $this->createRequest('GET', 'http://'.$repository->getIp(). ':8006/ogrepository/v1/status');
|
||||
|
||||
if (isset($content['error']) && $content['code'] === Response::HTTP_INTERNAL_SERVER_ERROR) {
|
||||
throw new BadRequestHttpException('An error occurred while fetching the status: ' . $content['details']);
|
||||
}
|
||||
}
|
||||
|
||||
$image = $input->name;
|
||||
private function getOrCreateImageEntity(string $imageName): Image
|
||||
{
|
||||
$imageEntity = $this->entityManager->getRepository(Image::class)->findOneBy(['name' => $imageName]);
|
||||
|
||||
$imageEntity = $this->entityManager->getRepository(Image::class)->findOneBy(['name' => $image]);
|
||||
|
||||
if (!$imageEntity){
|
||||
if (!$imageEntity) {
|
||||
$imageEntity = new Image();
|
||||
$imageEntity->setName($image);
|
||||
$imageEntity->setName($imageName);
|
||||
$imageEntity->setType('monolithic');
|
||||
$imageEntity->setRemotePc(false);
|
||||
$imageEntity->setIsGlobal(false);
|
||||
|
@ -51,65 +84,97 @@ class ImportAction extends AbstractOgRepositoryController
|
|||
$this->entityManager->persist($imageEntity);
|
||||
}
|
||||
|
||||
$imageImageRepositoryEntity = $this->entityManager->getRepository(ImageImageRepository::class)->findOneBy(['image' => $imageEntity, 'repository' => $repository]);
|
||||
return $imageEntity;
|
||||
}
|
||||
|
||||
if ($imageImageRepositoryEntity){
|
||||
private function validateImageNotExistsInRepository(Image $imageEntity, ImageRepository $repository): void
|
||||
{
|
||||
$imageImageRepositoryEntity = $this->entityManager->getRepository(ImageImageRepository::class)
|
||||
->findOneBy(['image' => $imageEntity, 'repository' => $repository]);
|
||||
|
||||
if ($imageImageRepositoryEntity) {
|
||||
throw new BadRequestHttpException('This image already exists in this repository');
|
||||
}
|
||||
}
|
||||
|
||||
$imageImageRepositoryEntity = new ImageImageRepository();
|
||||
$imageImageRepositoryEntity->setName($imageEntity->getName());
|
||||
$imageImageRepositoryEntity->setStatus(ImageStatus::AUX_FILES_PENDING);
|
||||
$imageImageRepositoryEntity->setImage($imageEntity);
|
||||
$imageImageRepositoryEntity->setRepository($repository);
|
||||
$imageImageRepositoryEntity->setVersion($this->extractVersionFromImageName($image));
|
||||
|
||||
$this->entityManager->persist($imageImageRepositoryEntity);
|
||||
$this->entityManager->flush();
|
||||
|
||||
$this->logger->info('Creating aux files', ['image' => $image]);
|
||||
|
||||
private function createTorrentSumRequest(ImageRepository $repository, string $image): array
|
||||
{
|
||||
$params = [
|
||||
'json' => [
|
||||
'image' => $image.'.img'
|
||||
]
|
||||
];
|
||||
|
||||
$content = $this->createRequest('POST', 'http://'.$repository->getIp().':8006/ogrepository/v1/images/torrentsum', $params);
|
||||
|
||||
if (isset($content['error']) && $content['code'] === Response::HTTP_INTERNAL_SERVER_ERROR ) {
|
||||
throw new BadRequestHttpException('Error importing image' . ' - ' . $content['error'] . ' - ' . $content['details']);
|
||||
}
|
||||
|
||||
$inputData = [
|
||||
'imageName' => $image,
|
||||
'imageImageRepositoryUuid' => $imageImageRepositoryEntity->getUuid(),
|
||||
];
|
||||
|
||||
$this->createService->__invoke(null, CommandTypes::CREATE_IMAGE_AUX_FILE, TraceStatus::IN_PROGRESS, $content['job_id'], $inputData);
|
||||
|
||||
return new JsonResponse(data: [], status: Response::HTTP_OK);
|
||||
return $this->createRequest('POST', 'http://'.$repository->getIp().':8006/ogrepository/v1/images/torrentsum', $params);
|
||||
}
|
||||
|
||||
private function handleTorrentSumResponse(array $content): void
|
||||
{
|
||||
if (!isset($content['error'])) {
|
||||
return;
|
||||
}
|
||||
|
||||
$errorMessage = $this->extractErrorMessage($content);
|
||||
$errorCode = $content['code'] ?? Response::HTTP_BAD_REQUEST;
|
||||
|
||||
$this->throwAppropriateException($errorCode, $errorMessage);
|
||||
}
|
||||
|
||||
private function extractErrorMessage(array $content): string
|
||||
{
|
||||
$errorMessage = $content['error'];
|
||||
$errorDetails = $content['details'] ?? null;
|
||||
|
||||
if (!$errorDetails) {
|
||||
return $errorMessage;
|
||||
}
|
||||
|
||||
if (is_array($errorDetails)) {
|
||||
return $errorDetails['message'] ?? $errorDetails['error'] ?? $errorMessage;
|
||||
}
|
||||
|
||||
if (is_string($errorDetails) && !empty($errorDetails)) {
|
||||
return $errorDetails;
|
||||
}
|
||||
|
||||
return $errorMessage;
|
||||
}
|
||||
|
||||
private function throwAppropriateException(int $errorCode, string $errorMessage): void
|
||||
{
|
||||
if ($errorCode >= 400 && $errorCode < 500) {
|
||||
throw new BadRequestHttpException($errorMessage);
|
||||
}
|
||||
|
||||
if ($errorCode >= 500) {
|
||||
throw new HttpException($errorCode, $errorMessage);
|
||||
}
|
||||
|
||||
throw new BadRequestHttpException($errorMessage);
|
||||
}
|
||||
|
||||
private function createImageImageRepositoryEntity(Image $imageEntity, ImageRepository $repository, string $imageName): ImageImageRepository
|
||||
{
|
||||
$imageImageRepositoryEntity = new ImageImageRepository();
|
||||
$imageImageRepositoryEntity->setName($imageEntity->getName());
|
||||
$imageImageRepositoryEntity->setStatus(ImageStatus::AUX_FILES_PENDING);
|
||||
$imageImageRepositoryEntity->setImage($imageEntity);
|
||||
$imageImageRepositoryEntity->setRepository($repository);
|
||||
$imageImageRepositoryEntity->setVersion($this->extractVersionFromImageName($imageName));
|
||||
|
||||
return $imageImageRepositoryEntity;
|
||||
}
|
||||
|
||||
private function extractVersionFromImageName(string $imageName): int
|
||||
{
|
||||
// Buscar patrones como "_v2", "_v3", etc.
|
||||
if (preg_match('/_v(\d+)$/', $imageName, $matches)) {
|
||||
return (int) $matches[1];
|
||||
$patterns = ['/_v(\d+)$/', '/-v(\d+)$/', '/v(\d+)$/'];
|
||||
|
||||
foreach ($patterns as $pattern) {
|
||||
if (preg_match($pattern, $imageName, $matches)) {
|
||||
return (int) $matches[1];
|
||||
}
|
||||
}
|
||||
|
||||
// Buscar patrones como "-v2", "-v3", etc.
|
||||
if (preg_match('/-v(\d+)$/', $imageName, $matches)) {
|
||||
return (int) $matches[1];
|
||||
}
|
||||
|
||||
// Buscar patrones como "v2", "v3" al final del nombre
|
||||
if (preg_match('/v(\d+)$/', $imageName, $matches)) {
|
||||
return (int) $matches[1];
|
||||
}
|
||||
|
||||
// Si no se encuentra ningún patrón de versión, devolver 1 por defecto
|
||||
return 1;
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue