refs #1975. Integration ogGit. Crete image and deploy
testing/ogcore-api/pipeline/head There was a failure building this commit
Details
testing/ogcore-api/pipeline/head There was a failure building this commit
Details
parent
af5ad81199
commit
e51e1e13ea
|
@ -42,7 +42,14 @@ class ChangeOrganizationalUnitAction extends AbstractController
|
|||
$clientEntity->setOrganizationalUnit($organizationalUnit);
|
||||
|
||||
$this->entityManager->persist($clientEntity);
|
||||
$this->postAction->__invoke($clientEntity, $clientEntity->getTemplate());
|
||||
|
||||
$template = $clientEntity->getTemplate() ?? $clientEntity->getOrganizationalUnit()->getNetworkSettings()?->getTemplate();
|
||||
|
||||
if (!$template) {
|
||||
throw new BadRequestHttpException('No template found for client');
|
||||
}
|
||||
|
||||
$this->postAction->__invoke($clientEntity, $template);
|
||||
}
|
||||
|
||||
$this->entityManager->flush();
|
||||
|
|
|
@ -8,6 +8,7 @@ use ApiPlatform\Validator\ValidatorInterface;
|
|||
use App\Dto\Input\DeployImageInput;
|
||||
use App\Entity\Command;
|
||||
use App\Entity\Image;
|
||||
use App\Model\ClientStatus;
|
||||
use App\Entity\ImageImageRepository;
|
||||
use App\Entity\OrganizationalUnit;
|
||||
use App\Entity\Partition;
|
||||
|
@ -31,11 +32,10 @@ class DeployImageAction extends AbstractController
|
|||
protected readonly EntityManagerInterface $entityManager,
|
||||
protected readonly HttpClientInterface $httpClient,
|
||||
protected readonly CreateService $createService,
|
||||
protected readonly ValidatorInterface $validator,
|
||||
protected readonly ValidatorInterface $validator,
|
||||
public readonly \App\Controller\OgAgent\DeployImageAction $deployImageOgAgentAction,
|
||||
public readonly \App\Controller\OgRepository\Image\DeployImageAction $deployImageOgRepositoryAction,
|
||||
)
|
||||
{
|
||||
) {
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -47,90 +47,117 @@ class DeployImageAction extends AbstractController
|
|||
{
|
||||
$this->validator->validate($input);
|
||||
|
||||
switch ($input->method){
|
||||
case DeployMethodTypes::UNICAST:
|
||||
case DeployMethodTypes::UNICAST_DIRECT:
|
||||
foreach ($input->clients as $client) {
|
||||
$inputData = [
|
||||
'method' => $input->method,
|
||||
'client' => $client->getEntity()->getUuid(),
|
||||
'image' => $image->getUuid(),
|
||||
'imageName' => $image->getName(),
|
||||
'numDisk' => (string) $input->diskNumber,
|
||||
'numPartition' => (string) $input->partitionNumber,
|
||||
];
|
||||
|
||||
$agentJobId = $this->deployImageOgAgentAction->__invoke($image, $input, $client->getEntity(), DeployMethodTypes::UNICAST);
|
||||
if (!$agentJobId){
|
||||
continue;
|
||||
}
|
||||
|
||||
$this->createService->__invoke($client->getEntity(), CommandTypes::DEPLOY_IMAGE, TraceStatus::IN_PROGRESS, $agentJobId, $inputData);
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
case DeployMethodTypes::MULTICAST_UFTP:
|
||||
case DeployMethodTypes::MULTICAST_UFTP_DIRECT:
|
||||
case DeployMethodTypes::MULTICAST_UDPCAST:
|
||||
case DeployMethodTypes::MULTICAST_UDPCAST_DIRECT:
|
||||
foreach ($input->clients as $client) {
|
||||
$inputData = [
|
||||
'method' => $input->method,
|
||||
'client' => $client->getEntity()->getUuid(),
|
||||
'image' => $image->getUuid(),
|
||||
'mcastIp' => $input->mcastIp,
|
||||
'mcastPort' => $input->mcastPort,
|
||||
'mcastSpeed' => $input->mcastSpeed,
|
||||
'mcastMode' => $input->mcastMode,
|
||||
'numDisk' => (string) $input->diskNumber,
|
||||
'numPartition' => (string) $input->partitionNumber,
|
||||
];
|
||||
|
||||
try {
|
||||
$this->deployImageOgRepositoryAction->__invoke($input, $image, $client->getEntity());
|
||||
} catch (\Exception $e) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$agentJobId = $this->deployImageOgAgentAction->__invoke($image, $input, $client->getEntity(), DeployMethodTypes::MULTICAST);
|
||||
if (!$agentJobId){
|
||||
continue;
|
||||
}
|
||||
|
||||
$this->createService->__invoke($client->getEntity(), CommandTypes::DEPLOY_IMAGE, TraceStatus::IN_PROGRESS, $agentJobId, $inputData);
|
||||
}
|
||||
break;
|
||||
|
||||
case DeployMethodTypes::TORRENT:
|
||||
foreach ($input->clients as $client) {
|
||||
$inputData = [
|
||||
'method' => $input->method,
|
||||
'client' => $client->getEntity()->getUuid(),
|
||||
'image' => $image->getUuid(),
|
||||
'p2pMode' => $input->p2pMode,
|
||||
'p2pTime' => $input->p2pTime,
|
||||
'numDisk' => (string) $input->diskNumber,
|
||||
'numPartition' => (string) $input->partitionNumber,
|
||||
];
|
||||
|
||||
try {
|
||||
$this->deployImageOgRepositoryAction->__invoke($input, $image, $client->getEntity(), $this->httpClient);
|
||||
} catch (\Exception $e) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$agentJobId = $this->deployImageOgAgentAction->__invoke($image, $input, $client->getEntity(), DeployMethodTypes::TORRENT);
|
||||
if (!$agentJobId){
|
||||
continue;
|
||||
}
|
||||
|
||||
$this->createService->__invoke($client->getEntity(), CommandTypes::DEPLOY_IMAGE, TraceStatus::IN_PROGRESS, $agentJobId, $inputData);
|
||||
}
|
||||
|
||||
break;
|
||||
if ($input->type === 'monolithic') {
|
||||
$this->handleMonolithicDeployment($input, $image);
|
||||
}
|
||||
|
||||
return new JsonResponse(data: [], status: Response::HTTP_OK);
|
||||
}
|
||||
|
||||
private function handleMonolithicDeployment(DeployImageInput $input, ImageImageRepository $image): void
|
||||
{
|
||||
switch ($input->method) {
|
||||
case DeployMethodTypes::UNICAST:
|
||||
case DeployMethodTypes::UNICAST_DIRECT:
|
||||
$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);
|
||||
break;
|
||||
case DeployMethodTypes::TORRENT:
|
||||
$this->handleTorrentDeployment($input, $image);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private function handleUnicastDeployment(DeployImageInput $input, ImageImageRepository $image): void
|
||||
{
|
||||
foreach ($input->clients as $client) {
|
||||
$inputData = $this->createInputData($input, $image, $client->getEntity());
|
||||
$this->processDeployment($client->getEntity(), $input, $image, $inputData, DeployMethodTypes::UNICAST);
|
||||
}
|
||||
}
|
||||
|
||||
private function handleMulticastDeployment(DeployImageInput $input, ImageImageRepository $image): void
|
||||
{
|
||||
foreach ($input->clients as $client) {
|
||||
$inputData = $this->createMulticastInputData($input, $image, $client->getEntity());
|
||||
|
||||
try {
|
||||
$this->deployImageOgRepositoryAction->__invoke($input, $image, $client->getEntity());
|
||||
} catch (\Exception $e) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$this->processDeployment($client->getEntity(), $input, $image, $inputData, DeployMethodTypes::MULTICAST);
|
||||
}
|
||||
}
|
||||
|
||||
private function handleTorrentDeployment(DeployImageInput $input, ImageImageRepository $image): void
|
||||
{
|
||||
foreach ($input->clients as $client) {
|
||||
$inputData = $this->createTorrentInputData($input, $image, $client->getEntity());
|
||||
|
||||
try {
|
||||
$response = $this->deployImageOgRepositoryAction->__invoke($input, $image, $client->getEntity(), $this->httpClient);
|
||||
|
||||
if (is_array($response) && isset($response['code']) && $response['code'] === 500) {
|
||||
throw new \Exception('Error del servidor OgRepository: ' . ($response['error'] ?? 'Error desconocido') . ' - ' . ($response['details'] ?? ''));
|
||||
}
|
||||
|
||||
} catch (\Exception $e) {
|
||||
throw $e;
|
||||
}
|
||||
|
||||
$this->processDeployment($client->getEntity(), $input, $image, $inputData, DeployMethodTypes::TORRENT);
|
||||
}
|
||||
}
|
||||
|
||||
private function processDeployment($client, DeployImageInput $input, ImageImageRepository $image, array $inputData, string $deployType): void
|
||||
{
|
||||
$agentJobId = $this->deployImageOgAgentAction->__invoke($image, $input, $client, $deployType);
|
||||
|
||||
if (!$agentJobId) {
|
||||
if ($input->queue) {
|
||||
$this->createService->__invoke($client, CommandTypes::DEPLOY_IMAGE, TraceStatus::PENDING, null, $inputData);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
$this->createService->__invoke($client, CommandTypes::DEPLOY_IMAGE, TraceStatus::IN_PROGRESS, $agentJobId, $inputData);
|
||||
}
|
||||
|
||||
private function createInputData(DeployImageInput $input, ImageImageRepository $image, $client): array
|
||||
{
|
||||
return [
|
||||
'method' => $input->method,
|
||||
'client' => $client->getUuid(),
|
||||
'image' => $image->getUuid(),
|
||||
'imageName' => $image->getName(),
|
||||
'numDisk' => (string) $input->diskNumber,
|
||||
'numPartition' => (string) $input->partitionNumber,
|
||||
'type' => $input->type,
|
||||
];
|
||||
}
|
||||
|
||||
private function createMulticastInputData(DeployImageInput $input, ImageImageRepository $image, $client): array
|
||||
{
|
||||
return array_merge($this->createInputData($input, $image, $client), [
|
||||
'mcastIp' => $input->mcastIp,
|
||||
'mcastPort' => $input->mcastPort,
|
||||
'mcastSpeed' => $input->mcastSpeed,
|
||||
'mcastMode' => $input->mcastMode,
|
||||
]);
|
||||
}
|
||||
|
||||
private function createTorrentInputData(DeployImageInput $input, ImageImageRepository $image, $client): array
|
||||
{
|
||||
return array_merge($this->createInputData($input, $image, $client), [
|
||||
'p2pMode' => $input->p2pMode,
|
||||
'p2pTime' => $input->p2pTime,
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,6 +4,7 @@ namespace App\Controller\OgAgent;
|
|||
|
||||
use App\Controller\OgRepository\Git\CreateRepositoryAction;
|
||||
use App\Controller\OgRepository\Git\CreateTagAction;
|
||||
use App\Controller\OgRepository\Git\SshKeyAction;
|
||||
use App\Service\CreatePartitionService;
|
||||
use App\Service\Trace\CreateService;
|
||||
use Doctrine\ORM\EntityManagerInterface;
|
||||
|
@ -28,7 +29,7 @@ abstract class AbstractOgAgentController extends AbstractController
|
|||
protected readonly LoggerInterface $logger,
|
||||
protected readonly CreateService $createService,
|
||||
protected readonly CreateRepositoryAction $createRepositoryAction,
|
||||
protected readonly CreateTagAction $createTagAction,
|
||||
protected readonly SshKeyAction $sshKeyAction,
|
||||
#[Autowire(env: 'SSL_ENABLED')]
|
||||
private readonly string $sslEnabled,
|
||||
)
|
||||
|
|
|
@ -5,10 +5,9 @@ declare(strict_types=1);
|
|||
namespace App\Controller\OgAgent;
|
||||
|
||||
use App\Controller\OgRepository\Git\CreateRepositoryAction;
|
||||
use App\Controller\OgRepository\Git\CreateTagAction;
|
||||
use App\Entity\Client;
|
||||
use App\Entity\Command;
|
||||
use App\Entity\GitImageRepository;
|
||||
use App\Entity\GitRepository;
|
||||
use App\Entity\Image;
|
||||
use App\Entity\ImageImageRepository;
|
||||
use App\Entity\ImageRepository;
|
||||
|
@ -43,9 +42,11 @@ class CreateImageAction extends AbstractOgAgentController
|
|||
* @throws RedirectionExceptionInterface
|
||||
* @throws ClientExceptionInterface
|
||||
*/
|
||||
public function __invoke(Image $image, ?Partition $partition = null, ?Client $client = null): JsonResponse
|
||||
public function __invoke(bool $queue, Image $image, ?Partition $partition = null, ?Client $client = null, ?string $gitRepositoryName = null): JsonResponse
|
||||
{
|
||||
if (!$image->getClient()->getIp()) {
|
||||
$client = $client ?? $image->getClient();
|
||||
|
||||
if (!$client->getIp()) {
|
||||
throw new BadRequestHttpException('IP is required');
|
||||
}
|
||||
|
||||
|
@ -76,25 +77,13 @@ class CreateImageAction extends AbstractOgAgentController
|
|||
|
||||
$this->entityManager->persist($imageImageRepository);
|
||||
|
||||
return $this->createMonolithicImage($imageImageRepository, $partitionInfo, $image, $repository, $client);
|
||||
return $this->createMonolithicImage($imageImageRepository, $partitionInfo, $image, $repository, $client, $queue);
|
||||
} else {
|
||||
$repository = $image->getClient()->getRepository();
|
||||
$latestImageRepo = $this->entityManager->getRepository(GitImageRepository::class)->findLatestVersionByImageAndRepository($image, $repository);
|
||||
|
||||
$gitImageRepository = new GitImageRepository();
|
||||
$gitImageRepository->setName($image->getName().'_v'.($latestImageRepo ? $latestImageRepo->getVersion() + 1 : 1));
|
||||
$gitImageRepository->setImage($image);
|
||||
$gitImageRepository->setRepository($repository);
|
||||
$gitImageRepository->setStatus(ImageStatus::IN_PROGRESS);
|
||||
$gitImageRepository->setVersion($latestImageRepo ? $latestImageRepo->getVersion() + 1 : 1);
|
||||
$gitImageRepository->setTag('v'.($latestImageRepo ? $latestImageRepo->getVersion() + 1 : 1));
|
||||
$gitImageRepository->setCreated(false);
|
||||
|
||||
$this->entityManager->persist($gitImageRepository);
|
||||
$this->entityManager->persist($image);
|
||||
$this->entityManager->flush();
|
||||
|
||||
return $this->createGitImage($gitImageRepository, $partitionInfo, $image, $repository);
|
||||
|
||||
// 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);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -109,9 +98,19 @@ class CreateImageAction extends AbstractOgAgentController
|
|||
array $partitionInfo,
|
||||
Image $image,
|
||||
ImageRepository $repository,
|
||||
?Client $client = null
|
||||
?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'],
|
||||
|
@ -134,85 +133,219 @@ class CreateImageAction extends AbstractOgAgentController
|
|||
|
||||
$data['cpt'] = dechex($partitionTypeCode);
|
||||
} else {
|
||||
throw new Exception("El tipo de partición '$partitionCode' no se encontró en la lista.");
|
||||
throw new BadRequestHttpException("Invalid partition code: {$partitionCode}");
|
||||
}
|
||||
|
||||
$client = $client ?? $image->getClient();
|
||||
$this->logger->info('Creating image', ['image' => $image->getId()]);
|
||||
|
||||
$response = $this->createRequest(
|
||||
method: 'POST',
|
||||
url: 'https://'.$client->getIp().':8000/opengnsys/CrearImagen',
|
||||
params: [
|
||||
'json' => $data,
|
||||
],
|
||||
token: $client->getToken(),
|
||||
);
|
||||
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()]);
|
||||
$this->logger->info('Creating image', ['image' => $imageImageRepository->getName(), 'repository' => $repository->getIp()]);
|
||||
|
||||
if (isset($response['error']) && $response['code'] === Response::HTTP_INTERNAL_SERVER_ERROR) {
|
||||
throw new BadRequestHttpException('Error creating image');
|
||||
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
|
||||
);
|
||||
}
|
||||
|
||||
$jobId = $response['job_id'];
|
||||
|
||||
$client->setStatus(ClientStatus::BUSY);
|
||||
$this->entityManager->persist($client);
|
||||
$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);
|
||||
}
|
||||
|
||||
public function createGitImage(
|
||||
GitImageRepository $gitImageRepository,
|
||||
array $partitionInfo,
|
||||
Image $image,
|
||||
ImageRepository $repository
|
||||
array $partitionInfo,
|
||||
ImageRepository $repository,
|
||||
bool $queue = false,
|
||||
?string $gitRepositoryName = null
|
||||
): JsonResponse
|
||||
{
|
||||
if (!isset($partitonInfo)) {
|
||||
try {
|
||||
$this->createRepositoryAction->__invoke($image, $repository);
|
||||
} catch (Exception $e) {
|
||||
$this->logger->error('Error creating repository', ['repository' => $repository->getId(), 'error' => $e->getMessage()]);
|
||||
|
||||
return new JsonResponse(
|
||||
data: ['error' => $e->getMessage()],
|
||||
status: Response::HTTP_INTERNAL_SERVER_ERROR
|
||||
);
|
||||
}
|
||||
} else {
|
||||
try {
|
||||
$this->createTagAction->__invoke($image, $repository, $gitImageRepository);
|
||||
} catch (Exception $e) {
|
||||
$this->logger->error('Error creating tag', ['repository' => $repository->getId(), 'error' => $e->getMessage()]);
|
||||
|
||||
return new JsonResponse(
|
||||
data: ['error' => $e->getMessage()],
|
||||
status: Response::HTTP_INTERNAL_SERVER_ERROR
|
||||
);
|
||||
}
|
||||
if (!isset($partitionInfo['numDisk'], $partitionInfo['numPartition'], $partitionInfo['partitionCode'], $partitionInfo['filesystem'])) {
|
||||
throw new BadRequestHttpException('Missing required partition information');
|
||||
}
|
||||
|
||||
return new JsonResponse(
|
||||
data: ['message' => 'Repository created successfully'],
|
||||
status: Response::HTTP_OK
|
||||
);
|
||||
$client = $image->getClient();
|
||||
if (!$client->getIp() || !$client->getToken()) {
|
||||
throw new BadRequestHttpException('Client IP or token is missing');
|
||||
}
|
||||
|
||||
//TODO: llamar al endpoint del agente.
|
||||
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
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -38,7 +38,7 @@ class DeployImageAction extends AbstractOgAgentController
|
|||
* @throws TransportExceptionInterface
|
||||
* @throws ServerExceptionInterface
|
||||
*/
|
||||
public function __invoke(ImageImageRepository $imageImageRepository, DeployImageInput $input, Client $client, string $method)
|
||||
public function __invoke(ImageImageRepository $imageImageRepository, DeployImageInput $input, Client $client, ?string $method = null)
|
||||
{
|
||||
$image = $imageImageRepository->getImage();
|
||||
|
||||
|
@ -46,6 +46,10 @@ class DeployImageAction extends AbstractOgAgentController
|
|||
throw new BadRequestHttpException('IP is required');
|
||||
}
|
||||
|
||||
if ($input->type === 'git') {
|
||||
throw new BadRequestHttpException('Use DeployGitImageAction for Git images');
|
||||
}
|
||||
|
||||
$method = match ($input->method) {
|
||||
DeployMethodTypes::MULTICAST_UFTP_DIRECT, DeployMethodTypes::MULTICAST_UDPCAST_DIRECT, => 'multicast-direct',
|
||||
DeployMethodTypes::MULTICAST, DeployMethodTypes::MULTICAST_UFTP, DeployMethodTypes::MULTICAST_UDPCAST => 'multicast',
|
||||
|
@ -83,16 +87,22 @@ class DeployImageAction extends AbstractOgAgentController
|
|||
'ids' => '0'
|
||||
];
|
||||
|
||||
$url = 'https://'.$client->getIp().':8000/opengnsys/RestaurarImagen';
|
||||
|
||||
$response = $this->createRequest(
|
||||
method: 'POST',
|
||||
url: 'https://'.$client->getIp().':8000/opengnsys/RestaurarImagen',
|
||||
url: $url,
|
||||
params: [
|
||||
'json' => $data,
|
||||
],
|
||||
token: $client->getToken(),
|
||||
);
|
||||
|
||||
$this->logger->info('Deploying image', [ 'image' => $imageImageRepository->getName(), 'repository' => $repository->getIp()]);
|
||||
$this->logger->info('Deploying image', [
|
||||
'image' => $imageImageRepository->getName(),
|
||||
'repository' => $repository->getIp(),
|
||||
'client' => $client->getIp()
|
||||
]);
|
||||
|
||||
if (isset($response['error']) && $response['code'] === Response::HTTP_INTERNAL_SERVER_ERROR) {
|
||||
throw new BadRequestHttpException('Error deploying image');
|
||||
|
|
|
@ -166,14 +166,16 @@ class AgentSessionController extends AbstractController
|
|||
return new JsonResponse(['message' => 'Client not found'], Response::HTTP_NOT_FOUND);
|
||||
}
|
||||
|
||||
switch ($data['ostype']) {
|
||||
case 'Linux':
|
||||
$status = $client->getStatus();
|
||||
|
||||
switch ($status) {
|
||||
case ClientStatus::LINUX_SESSION:
|
||||
$client->setStatus(ClientStatus::LINUX);
|
||||
break;
|
||||
case 'Windows':
|
||||
case ClientStatus::WINDOWS_SESSION:
|
||||
$client->setStatus(ClientStatus::WINDOWS);
|
||||
break;
|
||||
case 'MacOS':
|
||||
case ClientStatus::MACOS_SESSION:
|
||||
$client->setStatus(ClientStatus::MACOS);
|
||||
break;
|
||||
|
||||
|
@ -187,7 +189,7 @@ class AgentSessionController extends AbstractController
|
|||
$this->logger->info('Client logged out', [
|
||||
'ip' => $data['ip'],
|
||||
'user' => $data['user'],
|
||||
'ostype' => $data['ostype'],
|
||||
'status' => $status,
|
||||
]);
|
||||
|
||||
return new JsonResponse([], Response::HTTP_OK);
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Controller\OgAgent\Webhook;
|
||||
|
||||
use App\Controller\OgRepository\Image\CreateAuxFilesAction;
|
||||
|
@ -36,7 +38,9 @@ use Symfony\Contracts\HttpClient\HttpClientInterface;
|
|||
class StatusController extends AbstractController
|
||||
{
|
||||
const string CREATE_IMAGE = 'RESPUESTA_CrearImagen';
|
||||
const string CREATE_IMAGE_GIT = 'RESPUESTA_CrearImagenGit';
|
||||
const string RESTORE_IMAGE = 'RESPUESTA_RestaurarImagen';
|
||||
const string RESTORE_IMAGE_GIT = 'RESPUESTA_RestaurarImagenGit';
|
||||
const string CONFIGURE_IMAGE = 'RESPUESTA_Configurar';
|
||||
const string HARDWARE_INVENTORY = 'RESPUESTA_InventarioHardware';
|
||||
const string SOFTWARE_INVENTORY = 'RESPUESTA_InventarioSoftware';
|
||||
|
@ -65,7 +69,6 @@ class StatusController extends AbstractController
|
|||
|
||||
$this->logger->info('Webhook data received', $data);
|
||||
|
||||
// Esta parte del codigo nos indica si el cliente se encuentra activo
|
||||
if (isset($data['iph']) && isset($data['timestamp'])) {
|
||||
$client = $this->entityManager->getRepository(Client::class)->findOneBy(['ip' => $data['iph']]);
|
||||
if (!$client) {
|
||||
|
@ -81,11 +84,37 @@ class StatusController extends AbstractController
|
|||
if (isset($data['progress'])){
|
||||
$trace = $this->entityManager->getRepository(Trace::class)->findOneBy(['jobId' => $data['job_id']]);
|
||||
if ($trace){
|
||||
$trace->setProgress($data['progress'] * 100);
|
||||
$trace->setProgress((int)($data['progress'] * 100));
|
||||
$this->entityManager->persist($trace);
|
||||
$this->entityManager->flush();
|
||||
}
|
||||
}
|
||||
|
||||
if (isset($data['nfn']) && $data['nfn'] === self::CREATE_IMAGE_GIT) {
|
||||
$trace = $this->entityManager->getRepository(Trace::class)->findOneBy(['jobId' => $data['job_id']]);
|
||||
|
||||
if (!$trace) {
|
||||
$this->logger->error('Trace not found', $data);
|
||||
return new JsonResponse(['message' => 'Trace not found'], Response::HTTP_NOT_FOUND);
|
||||
}
|
||||
|
||||
if ($data['res'] === 1) {
|
||||
$trace->setStatus(TraceStatus::SUCCESS);
|
||||
$trace->setFinishedAt(new \DateTime());
|
||||
} else {
|
||||
$trace->setStatus(TraceStatus::FAILED);
|
||||
$trace->setFinishedAt(new \DateTime());
|
||||
$trace->setOutput($data['der']);
|
||||
}
|
||||
|
||||
$client = $trace->getClient();
|
||||
$client->setStatus(ClientStatus::OG_LIVE);
|
||||
$this->entityManager->persist($client);
|
||||
$this->entityManager->persist($trace);
|
||||
$this->entityManager->flush();
|
||||
$this->logger->info('Git image creation completed.', ['job_id' => $data['job_id'], 'success' => $data['res'] === 1]);
|
||||
}
|
||||
|
||||
|
||||
if (isset($data['nfn']) && $data['nfn'] === self::CREATE_IMAGE) {
|
||||
$trace = $this->entityManager->getRepository(Trace::class)->findOneBy(['jobId' => $data['job_id']]);
|
||||
|
@ -142,7 +171,7 @@ class StatusController extends AbstractController
|
|||
$this->logger->info('Image updated. Success.', ['image' => (string) $imageImageRepository->getUuid()]);
|
||||
}
|
||||
|
||||
if (isset($data['nfn']) && ($data['nfn'] === self::RESTORE_IMAGE || $data['nfn'] === self::CONFIGURE_IMAGE)) {
|
||||
if (isset($data['nfn']) && ($data['nfn'] === self::RESTORE_IMAGE || $data['nfn'] === self::CONFIGURE_IMAGE || $data['nfn'] === self::RESTORE_IMAGE_GIT)) {
|
||||
$trace = $this->entityManager->getRepository(Trace::class)->findOneBy(['jobId' => $data['job_id']]);
|
||||
$client = $trace->getClient();
|
||||
|
||||
|
|
|
@ -45,7 +45,7 @@ abstract class AbstractOgRepositoryController extends AbstractController
|
|||
'accept' => 'application/json',
|
||||
'Content-Type' => 'application/json'
|
||||
],
|
||||
'timeout' => 10,
|
||||
'timeout' => 30,
|
||||
]);
|
||||
|
||||
try {
|
||||
|
@ -56,7 +56,7 @@ abstract class AbstractOgRepositoryController extends AbstractController
|
|||
|
||||
return [
|
||||
'code' => Response::HTTP_INTERNAL_SERVER_ERROR,
|
||||
'error' => 'Client/Server error',
|
||||
'error' => $e->getMessage(),
|
||||
'details' => $e->getMessage(),
|
||||
];
|
||||
} catch (TransportExceptionInterface $e) {
|
||||
|
@ -64,7 +64,7 @@ abstract class AbstractOgRepositoryController extends AbstractController
|
|||
|
||||
return [
|
||||
'code' => Response::HTTP_INTERNAL_SERVER_ERROR,
|
||||
'error' => 'Transport error',
|
||||
'error' => $e->getMessage(),
|
||||
'details' => $e->getMessage(),
|
||||
];
|
||||
}
|
||||
|
|
|
@ -4,8 +4,6 @@ namespace App\Dto\Input;
|
|||
|
||||
use ApiPlatform\Metadata\ApiProperty;
|
||||
use App\Dto\Output\ClientOutput;
|
||||
use App\Dto\Output\ImageOutput;
|
||||
use App\Dto\Output\PartitionOutput;
|
||||
use App\Validator\Constraints\ClientsHaveSamePartitionCount;
|
||||
use App\Validator\Constraints\OrganizationalUnitMulticastMode;
|
||||
use App\Validator\Constraints\OrganizationalUnitMulticastPort;
|
||||
|
@ -17,49 +15,63 @@ class DeployImageInput
|
|||
{
|
||||
#[Groups(['image-image-repository:write'])]
|
||||
#[ApiProperty(description: 'The type of the image deployment', example: "")]
|
||||
public ?string $type = null;
|
||||
public ?string $type = 'monolithic';
|
||||
|
||||
#[Groups(['image-image-repository:write'])]
|
||||
#[ApiProperty(description: 'The type of the image deployment', example: "")]
|
||||
#[ApiProperty(description: 'The deployment method', example: "unicast")]
|
||||
public ?string $method = null;
|
||||
|
||||
/**
|
||||
* @var ClientOutput[]
|
||||
*/
|
||||
#[Groups(['image-image-repository:write'])]
|
||||
#[ApiProperty(description: 'The client to deploy the image')]
|
||||
#[ApiProperty(description: 'The clients to deploy the image to')]
|
||||
public ?array $clients = [];
|
||||
|
||||
#[Groups(['image-image-repository:write'])]
|
||||
#[ApiProperty(description: 'The disk number to deploy to', example: 1)]
|
||||
public ?int $diskNumber = null;
|
||||
|
||||
#[Groups(['image-image-repository:write'])]
|
||||
#[ApiProperty(description: 'The partition number to deploy to', example: 1)]
|
||||
public ?int $partitionNumber = null;
|
||||
|
||||
#[OrganizationalUnitP2PMode]
|
||||
#[Groups(['image-image-repository:write'])]
|
||||
#[ApiProperty(description: 'P2P mode for torrent deployment', example: "seed")]
|
||||
public ?string $p2pMode = null;
|
||||
|
||||
#[Groups(['image-image-repository:write'])]
|
||||
#[ApiProperty(description: 'P2P time for torrent deployment', example: 3600)]
|
||||
public ?int $p2pTime = null;
|
||||
|
||||
#[Groups(['image-image-repository:write'])]
|
||||
#[ApiProperty(description: 'Multicast IP address', example: "239.255.255.250")]
|
||||
public ?string $mcastIp = null;
|
||||
|
||||
#[Groups(['image-image-repository:write'])]
|
||||
#[ApiProperty(description: 'Multicast speed in Mbps', example: 100)]
|
||||
public ?int $mcastSpeed = null;
|
||||
|
||||
#[OrganizationalUnitMulticastPort]
|
||||
#[Groups(['image-image-repository:write'])]
|
||||
#[ApiProperty(description: 'Multicast port', example: 8000)]
|
||||
public ?int $mcastPort = null;
|
||||
|
||||
#[OrganizationalUnitMulticastMode]
|
||||
#[Groups(['image-image-repository:write'])]
|
||||
#[ApiProperty(description: 'Multicast mode', example: "full")]
|
||||
public ?string $mcastMode = null;
|
||||
|
||||
#[Groups(['image-image-repository:write'])]
|
||||
#[ApiProperty(description: 'Maximum number of clients for multicast', example: 50)]
|
||||
public ?int $maxClients = null;
|
||||
|
||||
#[Groups(['image-image-repository:write'])]
|
||||
#[ApiProperty(description: 'Maximum time for deployment in seconds', example: 3600)]
|
||||
public ?int $maxTime = null;
|
||||
}
|
||||
|
||||
#[Groups(['image-image-repository:write'])]
|
||||
#[ApiProperty(description: 'Whether to queue the deployment', example: false)]
|
||||
public bool $queue = false;
|
||||
}
|
||||
|
|
|
@ -21,7 +21,6 @@ use Symfony\Component\Validator\Constraints as Assert;
|
|||
|
||||
final class ImageInput
|
||||
{
|
||||
#[Assert\NotBlank(message: 'validators.image.name.not_blank')]
|
||||
#[Groups(['image:write'])]
|
||||
#[ApiProperty(description: 'The name of the image', example: "Image 1")]
|
||||
public ?string $name = null;
|
||||
|
@ -73,6 +72,14 @@ final class ImageInput
|
|||
#[ApiProperty(description: 'The global property of the image')]
|
||||
public ?bool $isGlobal = false;
|
||||
|
||||
#[Groups(['image:write'])]
|
||||
#[ApiProperty(description: 'The queue property of the image')]
|
||||
public bool $queue = false;
|
||||
|
||||
#[Groups(['image:write'])]
|
||||
#[ApiProperty(description: 'The name of the Git repository to use for this image', example: "mi-repositorio")]
|
||||
public ?string $gitRepository = null;
|
||||
|
||||
public function __construct(?Image $image = null)
|
||||
{
|
||||
if (!$image) {
|
||||
|
|
|
@ -12,11 +12,13 @@ final class DeployMethodTypes
|
|||
public const string UNICAST = 'unicast';
|
||||
public const string UNICAST_DIRECT = 'unicast-direct';
|
||||
public const string TORRENT = 'p2p';
|
||||
public const string GIT = 'git';
|
||||
|
||||
private const array DEPLOYMENT_METHOD_TYPES = [
|
||||
self::MULTICAST => 'Multicast',
|
||||
self::UNICAST => 'Unicast',
|
||||
self::TORRENT => 'Torrent',
|
||||
self::GIT => 'Git',
|
||||
];
|
||||
|
||||
public static function getDeploymentMethodTypes(): array
|
||||
|
|
Loading…
Reference in New Issue