ogRepo new endpoints. Export/Import image
testing/ogcore-api/pipeline/head This commit looks good
Details
testing/ogcore-api/pipeline/head This commit looks good
Details
parent
e421a38079
commit
3c7fa26e32
|
@ -34,7 +34,7 @@ resources:
|
|||
class: ApiPlatform\Metadata\Post
|
||||
method: POST
|
||||
input: App\Dto\Input\WoLInput
|
||||
uriTemplate: /image-repositories/{uuid}/wol
|
||||
uriTemplate: /image-repositories/wol
|
||||
controller: App\Controller\OgRepository\WoLAction
|
||||
|
||||
get_collection_images_ogrepository:
|
||||
|
|
|
@ -6,6 +6,7 @@ namespace App\Controller\OgRepository;
|
|||
|
||||
use App\Service\Trace\CreateService;
|
||||
use Doctrine\ORM\EntityManagerInterface;
|
||||
use Psr\Log\LoggerInterface;
|
||||
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
|
||||
use Symfony\Component\HttpFoundation\JsonResponse;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
|
@ -24,6 +25,7 @@ abstract class AbstractOgRepositoryController extends AbstractController
|
|||
protected readonly EntityManagerInterface $entityManager,
|
||||
protected readonly HttpClientInterface $httpClient,
|
||||
protected readonly CreateService $createService,
|
||||
protected readonly LoggerInterface $logger,
|
||||
)
|
||||
{
|
||||
}
|
||||
|
|
|
@ -6,6 +6,9 @@ use App\Controller\OgRepository\AbstractOgRepositoryController;
|
|||
use App\Dto\Input\ExportImportImageRepositoryInput;
|
||||
use App\Entity\Image;
|
||||
use App\Entity\ImageRepository;
|
||||
use App\Model\CommandTypes;
|
||||
use App\Model\ImageStatus;
|
||||
use App\Model\TraceStatus;
|
||||
use Symfony\Component\HttpFoundation\JsonResponse;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
use Symfony\Component\HttpKernel\Attribute\AsController;
|
||||
|
@ -44,9 +47,18 @@ class ExportAction extends AbstractOgRepositoryController
|
|||
]
|
||||
];
|
||||
|
||||
$this->logger->info('Exporting image', ['image' => $image->getName(), 'repository' => $repository->getIp()]);
|
||||
|
||||
$content = $this->createRequest('PUT', 'http://'.$image->getRepository()->getIp().':8006/ogrepository/v1/repo/images', $params);
|
||||
|
||||
$image->setRepository($repository);
|
||||
$inputData = [
|
||||
'imageName' => $image->getName(),
|
||||
'imageUuid' => $image->getUuid(),
|
||||
];
|
||||
|
||||
$this->createService->__invoke($image->getClient(), CommandTypes::EXPORT_IMAGE, TraceStatus::IN_PROGRESS, $content['job_id'], $inputData);
|
||||
|
||||
$image->setStatus(ImageStatus::TRANSFERING);
|
||||
$this->entityManager->persist($image);
|
||||
$this->entityManager->flush();
|
||||
}
|
||||
|
|
|
@ -6,6 +6,9 @@ use App\Controller\OgRepository\AbstractOgRepositoryController;
|
|||
use App\Dto\Input\ExportImportImageRepositoryInput;
|
||||
use App\Entity\Image;
|
||||
use App\Entity\ImageRepository;
|
||||
use App\Model\CommandTypes;
|
||||
use App\Model\ImageStatus;
|
||||
use App\Model\TraceStatus;
|
||||
use Symfony\Component\HttpFoundation\JsonResponse;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
use Symfony\Component\HttpKernel\Attribute\AsController;
|
||||
|
@ -46,7 +49,14 @@ class ImportAction extends AbstractOgRepositoryController
|
|||
|
||||
$content = $this->createRequest('POST', 'http://'.$image->getRepository()->getIp().':8006/ogrepository/v1/repo/images', $params);
|
||||
|
||||
$image->setRepository($repository);
|
||||
$inputData = [
|
||||
'imageName' => $image->getName(),
|
||||
'imageUuid' => $image->getUuid(),
|
||||
];
|
||||
|
||||
$this->createService->__invoke($image->getClient(), CommandTypes::IMPORT_IMAGE, TraceStatus::IN_PROGRESS, $content['job_id'], $inputData);
|
||||
|
||||
$image->setStatus(ImageStatus::TRANSFERING);
|
||||
$this->entityManager->persist($image);
|
||||
$this->entityManager->flush();
|
||||
}
|
||||
|
|
|
@ -7,6 +7,7 @@ use App\Entity\Trace;
|
|||
use App\Model\ImageStatus;
|
||||
use App\Model\TraceStatus;
|
||||
use Doctrine\ORM\EntityManagerInterface;
|
||||
use Psr\Log\LoggerInterface;
|
||||
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
|
||||
use Symfony\Component\HttpFoundation\JsonResponse;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
|
@ -18,7 +19,8 @@ use Symfony\Component\Routing\Annotation\Route;
|
|||
class ResponseController extends AbstractController
|
||||
{
|
||||
public function __construct(
|
||||
protected readonly EntityManagerInterface $entityManager
|
||||
protected readonly EntityManagerInterface $entityManager,
|
||||
protected readonly LoggerInterface $logger,
|
||||
)
|
||||
{
|
||||
}
|
||||
|
@ -28,6 +30,27 @@ class ResponseController extends AbstractController
|
|||
{
|
||||
$data = json_decode($request->getContent(), true);
|
||||
|
||||
if (!isset($data['job_id'])) {
|
||||
return new JsonResponse(['message' => 'Invalid request'], Response::HTTP_BAD_REQUEST);
|
||||
}
|
||||
|
||||
$action = $data['job_id'];
|
||||
|
||||
if (str_starts_with($action, "CreateAuxiliarFiles_")) {
|
||||
$this->handleCreateAuxFiles($action, $data);
|
||||
} elseif (str_starts_with($action, "ExportImage_")) {
|
||||
$this->handleExportImage($action, $data);
|
||||
} elseif (str_starts_with($action, "ImportImage_")) {
|
||||
$this->handleImportImage($action, $data);
|
||||
} else {
|
||||
return new JsonResponse(['message' => 'Invalid action'], Response::HTTP_BAD_REQUEST);
|
||||
}
|
||||
|
||||
return new JsonResponse($data, Response::HTTP_OK);
|
||||
}
|
||||
|
||||
private function handleCreateAuxFiles(string $action, array $data): void
|
||||
{
|
||||
$trace = $this->entityManager->getRepository(Trace::class)->findOneBy(['jobId' => $data['job_id']]);
|
||||
$imageUuid = $trace->getInput()['imageUuid'];
|
||||
|
||||
|
@ -40,7 +63,8 @@ class ResponseController extends AbstractController
|
|||
$this->entityManager->persist($trace);
|
||||
$this->entityManager->flush();
|
||||
|
||||
return new JsonResponse(['message' => 'Image not found'], Response::HTTP_NOT_FOUND);
|
||||
new JsonResponse(['message' => 'Image not found'], Response::HTTP_NOT_FOUND);
|
||||
return;
|
||||
}
|
||||
|
||||
$image->setImageFullsum($data['image_id']);
|
||||
|
@ -52,8 +76,69 @@ class ResponseController extends AbstractController
|
|||
|
||||
$this->entityManager->persist($trace);
|
||||
$this->entityManager->flush();
|
||||
}
|
||||
|
||||
return new JsonResponse($data, Response::HTTP_OK);
|
||||
private function handleExportImage(string $action, array $data): void
|
||||
{
|
||||
$trace = $this->entityManager->getRepository(Trace::class)->findOneBy(['jobId' => $data['job_id']]);
|
||||
|
||||
$imageUuid = $trace->getInput()['imageUuid'];
|
||||
|
||||
$image = $this->entityManager->getRepository(Image::class)->findOneBy(['uuid' => $imageUuid]);
|
||||
|
||||
if ($image === null) {
|
||||
$trace->setStatus(TraceStatus::FAILED);
|
||||
$trace->setFinishedAt(new \DateTime());
|
||||
$trace->setOutput('Image not found');
|
||||
$this->entityManager->persist($trace);
|
||||
$this->entityManager->flush();
|
||||
|
||||
new JsonResponse(['message' => 'Image not found'], Response::HTTP_NOT_FOUND);
|
||||
return;
|
||||
}
|
||||
|
||||
$this->logger->info('Image exported', ['image' => $image->getName()]);
|
||||
|
||||
$image->setStatus(ImageStatus::SUCCESS);
|
||||
$this->entityManager->persist($image);
|
||||
|
||||
|
||||
$trace->setStatus(TraceStatus::SUCCESS);
|
||||
$trace->setFinishedAt(new \DateTime());
|
||||
|
||||
$this->entityManager->persist($trace);
|
||||
$this->entityManager->flush();
|
||||
}
|
||||
|
||||
private function handleImportImage(string $action, array $data): void
|
||||
{
|
||||
$trace = $this->entityManager->getRepository(Trace::class)->findOneBy(['jobId' => $data['job_id']]);
|
||||
|
||||
$imageUuid = $trace->getInput()['imageUuid'];
|
||||
|
||||
$image = $this->entityManager->getRepository(Image::class)->findOneBy(['uuid' => $imageUuid]);
|
||||
|
||||
if ($image === null) {
|
||||
$trace->setStatus(TraceStatus::FAILED);
|
||||
$trace->setFinishedAt(new \DateTime());
|
||||
$trace->setOutput('Image not found');
|
||||
$this->entityManager->persist($trace);
|
||||
$this->entityManager->flush();
|
||||
|
||||
new JsonResponse(['message' => 'Image not found'], Response::HTTP_NOT_FOUND);
|
||||
return;
|
||||
}
|
||||
|
||||
$this->logger->info('Image imported', ['image' => $image->getName()]);
|
||||
|
||||
$image->setStatus(ImageStatus::SUCCESS);
|
||||
$this->entityManager->persist($image);
|
||||
|
||||
|
||||
$trace->setStatus(TraceStatus::SUCCESS);
|
||||
$trace->setFinishedAt(new \DateTime());
|
||||
|
||||
$this->entityManager->persist($trace);
|
||||
$this->entityManager->flush();
|
||||
}
|
||||
}
|
|
@ -36,31 +36,35 @@ class WoLAction extends AbstractOgRepositoryController
|
|||
* @throws RedirectionExceptionInterface
|
||||
* @throws ClientExceptionInterface
|
||||
*/
|
||||
public function __invoke(WoLInput $input, ImageRepository $repository): JsonResponse
|
||||
public function __invoke(WoLInput $input): JsonResponse
|
||||
{
|
||||
/** @var Client $client */
|
||||
$client = $input->client->getEntity();
|
||||
foreach ($input->clients as $client) {
|
||||
/** @var Client $client */
|
||||
$client = $client->getEntity();
|
||||
$repository = $client->getRepository();
|
||||
|
||||
if (!$repository->getIp()) {
|
||||
throw new ValidatorException('IP is required');
|
||||
}
|
||||
|
||||
if (!$repository->getIp()) {
|
||||
throw new ValidatorException('IP is required');
|
||||
$params = [
|
||||
'json' => [
|
||||
'broadcast_ip' => '255.255.255.255',
|
||||
'mac' => $client->getMac()
|
||||
]
|
||||
];
|
||||
|
||||
$this->logger->info('Sending WoL to client', ['mac' => $client->getMac()]);
|
||||
|
||||
$content = $this->createRequest('POST', 'http://'.$repository->getIp(). ':8006/ogrepository/v1/wol', $params);
|
||||
|
||||
$client->setStatus(ClientStatus::INITIALIZING);
|
||||
$this->entityManager->persist($client);
|
||||
$this->entityManager->flush();
|
||||
|
||||
$this->createService->__invoke($client, CommandTypes::SHUTDOWN, TraceStatus::SUCCESS, '', []);
|
||||
}
|
||||
|
||||
$params = [
|
||||
'json' => [
|
||||
'broadcast_ip' => '255.255.255.255',
|
||||
'mac' => $client->getMac()
|
||||
]
|
||||
];
|
||||
|
||||
$content = $this->createRequest('POST', 'http://'.$repository->getIp(). ':8006/ogrepository/v1/wol', $params);
|
||||
|
||||
$client->setStatus(ClientStatus::INITIALIZING);
|
||||
$this->entityManager->persist($client);
|
||||
$this->entityManager->flush();
|
||||
|
||||
$this->createService->__invoke($client, CommandTypes::SHUTDOWN, TraceStatus::SUCCESS, '', []);
|
||||
|
||||
return new JsonResponse(data: $client, status: Response::HTTP_OK);
|
||||
return new JsonResponse(data: [], status: Response::HTTP_OK);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -38,6 +38,10 @@ final class ImageInput
|
|||
#[ApiProperty(description: 'The type of the image', example: "Server")]
|
||||
public ?string $source = 'input';
|
||||
|
||||
#[Groups(['image:write'])]
|
||||
#[ApiProperty(description: 'The status of the image', example: "PENDING")]
|
||||
public ?string $status = ImageStatus::PENDING;
|
||||
|
||||
#[Groups(['image:write'])]
|
||||
#[ApiProperty(description: 'The software profile of the image')]
|
||||
public ?SoftwareProfileOutput $softwareProfile = null;
|
||||
|
@ -73,6 +77,7 @@ final class ImageInput
|
|||
$this->comments = $image->getComments();
|
||||
$this->type = $image->getType();
|
||||
$this->remotePc = $image->isRemotePc();
|
||||
$this->status = $image->getStatus();
|
||||
|
||||
if ($image->getSoftwareProfile()) {
|
||||
$this->softwareProfile = new SoftwareProfileOutput($image->getSoftwareProfile());
|
||||
|
@ -95,13 +100,13 @@ final class ImageInput
|
|||
{
|
||||
if (!$image) {
|
||||
$image = new Image();
|
||||
$image->setStatus(ImageStatus::PENDING);
|
||||
}
|
||||
|
||||
$image->setName($this->name);
|
||||
$image->setDescription($this->description);
|
||||
$image->setComments($this->comments);
|
||||
$image->setType($this->type);
|
||||
$image->setStatus(ImageStatus::PENDING);
|
||||
|
||||
if ($this->softwareProfile) {
|
||||
$image->setSoftwareProfile($this->softwareProfile->getEntity());
|
||||
|
|
|
@ -8,7 +8,10 @@ use Symfony\Component\Serializer\Annotation\Groups;
|
|||
|
||||
class WoLInput
|
||||
{
|
||||
/**
|
||||
* @var ClientOutput[]|null
|
||||
*/
|
||||
#[Groups(['repository:write'])]
|
||||
#[ApiProperty(description: 'The client to wol')]
|
||||
public ?ClientOutput $client = null;
|
||||
public ?array $clients = null;
|
||||
}
|
|
@ -8,6 +8,8 @@ final class CommandTypes
|
|||
public const string RESTORE_IMAGE = 'restore-image';
|
||||
public const string CREATE_IMAGE = 'create-image';
|
||||
public const string CREATE_IMAGE_AUX_FILE = 'create-image-aux-file';
|
||||
public const string IMPORT_IMAGE = 'import-image';
|
||||
public const string EXPORT_IMAGE = 'export-image';
|
||||
public const string POWER_ON = 'power-on';
|
||||
public const string REBOOT = 'reboot';
|
||||
public const string SHUTDOWN = 'shutdown';
|
||||
|
@ -20,6 +22,8 @@ final class CommandTypes
|
|||
self::RESTORE_IMAGE => 'Update Cache',
|
||||
self::CREATE_IMAGE => 'Create Image',
|
||||
self::CREATE_IMAGE_AUX_FILE => 'Crear fichero auxiliar en repositorio',
|
||||
self::IMPORT_IMAGE => 'Importar imagen',
|
||||
self::EXPORT_IMAGE => 'Exportar imagen',
|
||||
self::POWER_ON => 'Encender',
|
||||
self::REBOOT => 'Reiniciar',
|
||||
self::SHUTDOWN => 'Apagar',
|
||||
|
|
|
@ -10,6 +10,7 @@ final class ImageStatus
|
|||
public const string SUCCESS = 'success';
|
||||
public const string TRASH = 'trash';
|
||||
public const string FAILED = 'failed';
|
||||
public const string TRANSFERING = 'transfering';
|
||||
|
||||
private const array STATUS = [
|
||||
self::PENDING => 'Pendiente',
|
||||
|
@ -18,6 +19,7 @@ final class ImageStatus
|
|||
self::TRASH => 'Papelera',
|
||||
self::SUCCESS => 'Completado',
|
||||
self::FAILED => 'Fallido',
|
||||
self::TRANSFERING => 'Transferiendo',
|
||||
];
|
||||
|
||||
public static function getStatus(): array
|
||||
|
|
Loading…
Reference in New Issue