refs #1984. Git integration UX changes

pull/30/head
Manuel Aranda Rosales 2025-05-12 16:35:40 +02:00
parent 816b31a7ed
commit 1f6f4164d0
21 changed files with 517 additions and 74 deletions

View File

@ -107,7 +107,7 @@ services:
api_platform.filter.image.search:
parent: 'api_platform.doctrine.orm.search_filter'
arguments: [ { 'id': 'exact', 'name': 'partial', 'repository.id': 'exact', status: 'exact'} ]
arguments: [ { 'id': 'exact', 'name': 'partial', 'repository.id': 'exact', status: 'exact', type: 'exact' } ]
tags: [ 'api_platform.filter' ]
api_platform.filter.image.boolean:

View File

@ -0,0 +1,31 @@
<?php
declare(strict_types=1);
namespace DoctrineMigrations;
use Doctrine\DBAL\Schema\Schema;
use Doctrine\Migrations\AbstractMigration;
/**
* Auto-generated Migration: Please modify to your needs!
*/
final class Version20250508152437 extends AbstractMigration
{
public function getDescription(): string
{
return '';
}
public function up(Schema $schema): void
{
// this up() migration is auto-generated, please modify it to your needs
$this->addSql('ALTER TABLE image ADD type VARCHAR(255) NOT NULL, DROP description, DROP comments');
}
public function down(Schema $schema): void
{
// this down() migration is auto-generated, please modify it to your needs
$this->addSql('ALTER TABLE image ADD description VARCHAR(255) DEFAULT NULL, ADD comments VARCHAR(255) DEFAULT NULL, DROP type');
}
}

View File

@ -0,0 +1,39 @@
<?php
declare(strict_types=1);
namespace DoctrineMigrations;
use Doctrine\DBAL\Schema\Schema;
use Doctrine\Migrations\AbstractMigration;
/**
* Auto-generated Migration: Please modify to your needs!
*/
final class Version20250512071804 extends AbstractMigration
{
public function getDescription(): string
{
return '';
}
public function up(Schema $schema): void
{
// this up() migration is auto-generated, please modify it to your needs
$this->addSql('ALTER TABLE git_image_repository DROP FOREIGN KEY FK_E6944D5E14C736FC');
$this->addSql('DROP INDEX IDX_E6944D5E14C736FC ON git_image_repository');
$this->addSql('ALTER TABLE git_image_repository ADD tag VARCHAR(255) NOT NULL, CHANGE image_repository_id repository_id INT DEFAULT NULL');
$this->addSql('ALTER TABLE git_image_repository ADD CONSTRAINT FK_E6944D5E50C9D4F7 FOREIGN KEY (repository_id) REFERENCES image_repository (id)');
$this->addSql('CREATE INDEX IDX_E6944D5E50C9D4F7 ON git_image_repository (repository_id)');
}
public function down(Schema $schema): void
{
// this down() migration is auto-generated, please modify it to your needs
$this->addSql('ALTER TABLE git_image_repository DROP FOREIGN KEY FK_E6944D5E50C9D4F7');
$this->addSql('DROP INDEX IDX_E6944D5E50C9D4F7 ON git_image_repository');
$this->addSql('ALTER TABLE git_image_repository DROP tag, CHANGE repository_id image_repository_id INT DEFAULT NULL');
$this->addSql('ALTER TABLE git_image_repository ADD CONSTRAINT FK_E6944D5E14C736FC FOREIGN KEY (image_repository_id) REFERENCES image_repository (id)');
$this->addSql('CREATE INDEX IDX_E6944D5E14C736FC ON git_image_repository (image_repository_id)');
}
}

View File

@ -0,0 +1,31 @@
<?php
declare(strict_types=1);
namespace DoctrineMigrations;
use Doctrine\DBAL\Schema\Schema;
use Doctrine\Migrations\AbstractMigration;
/**
* Auto-generated Migration: Please modify to your needs!
*/
final class Version20250512075927 extends AbstractMigration
{
public function getDescription(): string
{
return '';
}
public function up(Schema $schema): void
{
// this up() migration is auto-generated, please modify it to your needs
$this->addSql('ALTER TABLE git_image_repository CHANGE branch branch VARCHAR(255) DEFAULT NULL');
}
public function down(Schema $schema): void
{
// this down() migration is auto-generated, please modify it to your needs
$this->addSql('ALTER TABLE git_image_repository CHANGE branch branch VARCHAR(255) NOT NULL');
}
}

View File

@ -0,0 +1,31 @@
<?php
declare(strict_types=1);
namespace DoctrineMigrations;
use Doctrine\DBAL\Schema\Schema;
use Doctrine\Migrations\AbstractMigration;
/**
* Auto-generated Migration: Please modify to your needs!
*/
final class Version20250512081045 extends AbstractMigration
{
public function getDescription(): string
{
return '';
}
public function up(Schema $schema): void
{
// this up() migration is auto-generated, please modify it to your needs
$this->addSql('ALTER TABLE git_image_repository ADD version INT DEFAULT NULL');
}
public function down(Schema $schema): void
{
// this down() migration is auto-generated, please modify it to your needs
$this->addSql('ALTER TABLE git_image_repository DROP version');
}
}

View File

@ -4,8 +4,11 @@ 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\Image;
use App\Entity\ImageImageRepository;
use App\Entity\ImageRepository;
@ -38,6 +41,8 @@ class CreateImageAction extends AbstractController
protected readonly HttpClientInterface $httpClient,
protected readonly CreateService $createService,
protected readonly LoggerInterface $logger,
protected readonly CreateRepositoryAction $createRepositoryAction,
protected readonly CreateTagAction $createTagAction,
)
{
}
@ -67,18 +72,54 @@ class CreateImageAction extends AbstractController
$partitionInfo = json_decode($image->getPartitionInfo(), true);
}
$repository = $image->getClient()->getRepository();
$latestImageRepo = $this->entityManager->getRepository(ImageImageRepository::class)->findLatestVersionByImageAndRepository($image, $repository);
if ($image->getType() === 'monolithic') {
$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);
$repository = $image->getClient()->getRepository();
$latestImageRepo = $this->entityManager->getRepository(ImageImageRepository::class)->findLatestVersionByImageAndRepository($image, $repository);
$this->entityManager->persist($imageImageRepository);
$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);
return $this->createMonolithicImage($imageImageRepository, $partitionInfo, $image, $repository);
} 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->flush();
return $this->createGitImage($gitImageRepository, $partitionInfo, $image, $repository);
}
}
/**
* @throws TransportExceptionInterface
* @throws ServerExceptionInterface
* @throws RedirectionExceptionInterface
* @throws ClientExceptionInterface
*/
public function createMonolithicImage(
ImageImageRepository $imageImageRepository,
array $partitionInfo,
Image $image,
ImageRepository $repository
): JsonResponse
{
$data = [
'dsk' => (string) $partitionInfo['numDisk'],
'par' => (string) $partitionInfo['numPartition'],
@ -135,4 +176,43 @@ class CreateImageAction extends AbstractController
return new JsonResponse(data: $image, status: Response::HTTP_OK);
}
public function createGitImage(
GitImageRepository $gitImageRepository,
array $partitionInfo,
Image $image,
ImageRepository $repository
): 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
);
}
}
return new JsonResponse(
data: ['message' => 'Repository created successfully'],
status: Response::HTTP_OK
);
//TODO: llamar al endpoint del agente.
}
}

View File

@ -0,0 +1,42 @@
<?php
namespace App\Controller\OgRepository\Git;
use App\Controller\OgRepository\AbstractOgRepositoryController;
use App\Entity\Image;
use App\Entity\ImageRepository;
use Symfony\Component\HttpKernel\Attribute\AsController;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Response;
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;
#[AsController]
class CreateRepositoryAction extends AbstractOgRepositoryController
{
/**
* @throws TransportExceptionInterface
* @throws ServerExceptionInterface
* @throws RedirectionExceptionInterface
* @throws ClientExceptionInterface
*/
public function __invoke(Image $image, ImageRepository $repository): JsonResponse
{
$params = [
'json' => [
'name' => $image->getName(),
]
];
$content = $this->createRequest('POST', 'http://'.$repository->getIp().':8006/ogrepository/v1/git/repositories', $params);
if (isset($content['error']) && $content['code'] === Response::HTTP_INTERNAL_SERVER_ERROR ) {
throw new ValidatorException('Error creating repository');
}
return new JsonResponse(data: [], status: Response::HTTP_OK);
}
}

View File

@ -0,0 +1,46 @@
<?php
namespace App\Controller\OgRepository\Git;
use App\Controller\OgRepository\AbstractOgRepositoryController;
use App\Entity\GitImageRepository;
use App\Entity\Image;
use App\Entity\ImageRepository;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Attribute\AsController;
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;
#[AsController]
class CreateTagAction extends AbstractOgRepositoryController
{
/**
* @throws TransportExceptionInterface
* @throws ServerExceptionInterface
* @throws RedirectionExceptionInterface
* @throws ClientExceptionInterface
*/
public function __invoke(Image $image, ImageRepository $repository, GitImageRepository $gitImageRepository): JsonResponse
{
$params = [
'json' => [
'commit' => "HEAD",
'message' => $gitImageRepository->getVersion(),
'name' => $image->getName(),
]
];
$content = $this->createRequest('POST', 'http://'.$repository->getIp().':8006/ogrepository/v1/git/repositories/'.
$image->getName().'/tags', $params);
if (isset($content['error']) && $content['code'] === Response::HTTP_INTERNAL_SERVER_ERROR ) {
throw new ValidatorException('Error creating repository');
}
return new JsonResponse(data: [], status: Response::HTTP_OK);
}
}

View File

@ -27,16 +27,12 @@ final class ImageInput
public ?string $name = null;
#[Groups(['image:write'])]
#[ApiProperty(description: 'The description of the image', example: "Image 1 description")]
public ?string $description = null;
#[Groups(['image:write'])]
#[ApiProperty(description: 'The comments of the image', example: "Image 1 comments")]
public ?string $comments = null;
#[ApiProperty(description: 'The type of the image', example: "Server")]
public ?string $source = 'input';
#[Groups(['image:write'])]
#[ApiProperty(description: 'The type of the image', example: "Server")]
public ?string $source = 'input';
public ?string $type = '';
#[Groups(['image:write'])]
#[ApiProperty(description: 'The optional selected image')]
@ -84,8 +80,7 @@ final class ImageInput
}
$this->name = $image->getName();
$this->description = $image->getDescription();
$this->comments = $image->getComments();
$this->type = $image->getType();
$this->remotePc = $image->isRemotePc();
$this->isGlobal = $image->isGlobal();
$this->version = $image->getVersion();
@ -114,8 +109,7 @@ final class ImageInput
}
$image->setName($this->name);
$image->setDescription($this->description);
$image->setComments($this->comments);
$image->setType($this->type);
if ($this->softwareProfile) {
$image->setSoftwareProfile($this->softwareProfile->getEntity());

View File

@ -23,7 +23,10 @@ final class GitImageRepositoryOutput extends AbstractOutput
public string $name = '';
#[Groups(['git-image-repository:read', 'image:read'])]
public string $branch = '';
public ?string $branch = '';
#[Groups(['git-image-repository:read', 'image:read'])]
public ?string $tag = '';
#[Groups(['git-image-repository:read', 'image:read'])]
public \DateTime $createdAt;
@ -41,13 +44,14 @@ final class GitImageRepositoryOutput extends AbstractOutput
}
}
if ($gitImageRepository->getImageRepository()) {
$this->imageRepository = new ImageRepositoryOutput($gitImageRepository->getImageRepository());
if ($gitImageRepository->getRepository()) {
$this->imageRepository = new ImageRepositoryOutput($gitImageRepository->getRepository());
}
$this->name = $gitImageRepository->getName();
$this->status = $gitImageRepository->getStatus();
$this->branch = $gitImageRepository->getBranch();
$this->tag = $gitImageRepository->getTag();
$this->createdAt = $gitImageRepository->getCreatedAt();
$this->createdBy = $gitImageRepository->getCreatedBy();
}

View File

@ -14,19 +14,15 @@ final class ImageOutput extends AbstractOutput
{
#[Groups(['image:read', 'image-image-repository:read'])]
public ?string $name = '';
#[Groups(['image:read'])]
public ?string $description = '';
#[Groups(['image:read'])]
public ?string $comments = '';
#[Groups(['image:read', 'image-image-repository:read'])]
public ?bool $remotePc = null;
#[Groups(['image:read', 'image-image-repository:read'])]
public ?bool $isGlobal = null;
#[Groups(['image:read', 'image-image-repository:read'])]
public ?string $type = '';
#[Groups(['image:read'])]
public ?SoftwareProfileOutput $softwareProfile = null;
@ -53,8 +49,6 @@ final class ImageOutput extends AbstractOutput
parent::__construct($image);
$this->name = $image->getName();
$this->description = $image->getDescription();
$this->comments = $image->getComments();
$this->softwareProfile = $image->getSoftwareProfile() ? new SoftwareProfileOutput($image->getSoftwareProfile()) : null;
$this->imageRepositories = $image->getImageImageRepositories()->map(
@ -62,6 +56,7 @@ final class ImageOutput extends AbstractOutput
)->toArray();
$this->version = $image->getVersion();
$this->type = $image->getType();
$this->partitionInfo = json_decode($image->getPartitionInfo(), true);
$this->remotePc = $image->isRemotePc();
$this->isGlobal = $image->isGlobal();

View File

@ -40,7 +40,7 @@ final class OgLiveOutput extends AbstractOutput
#[Groups(['og-live:read', 'client:read', "organizational-unit:read"])]
public ?string $filename = null;
#[Groups(['og-live:read'])]
#[Groups(['og-live:read', 'client:read', "organizational-unit:read"])]
public ?string $kernel = '';
#[Groups(['og-live:read'])]

View File

@ -15,14 +15,20 @@ class GitImageRepository extends AbstractEntity
private ?Image $image = null;
#[ORM\ManyToOne(inversedBy: 'gitImageRepositories')]
private ?ImageRepository $imageRepository = null;
private ?ImageRepository $repository = null;
#[ORM\Column(length: 255)]
private ?string $status = null;
#[ORM\Column(length: 255)]
#[ORM\Column(length: 255, nullable: true)]
private ?string $branch = null;
#[ORM\Column(length: 255)]
private ?string $tag = null;
#[ORM\Column(nullable: true)]
private ?int $version = null;
#[ORM\Column]
private ?bool $created = null;
@ -56,13 +62,37 @@ class GitImageRepository extends AbstractEntity
return $this->branch;
}
public function setBranch(string $branch): static
public function setBranch(?string $branch): static
{
$this->branch = $branch;
return $this;
}
public function getTag(): ?string
{
return $this->tag;
}
public function setTag(?string $tag): static
{
$this->tag = $tag;
return $this;
}
public function getVersion(): ?int
{
return $this->version;
}
public function setVersion(?int $version): static
{
$this->version = $version;
return $this;
}
public function isCreated(): ?bool
{
return $this->created;
@ -75,14 +105,14 @@ class GitImageRepository extends AbstractEntity
return $this;
}
public function getImageRepository(): ?ImageRepository
public function getRepository(): ?ImageRepository
{
return $this->imageRepository;
return $this->repository;
}
public function setImageRepository(?ImageRepository $imageRepository): static
public function setRepository(?ImageRepository $imageRepository): static
{
$this->imageRepository = $imageRepository;
$this->repository = $imageRepository;
return $this;
}

View File

@ -15,12 +15,6 @@ class Image extends AbstractEntity
{
use NameableTrait;
#[ORM\Column(length: 255, nullable: true)]
private ?string $description = null;
#[ORM\Column(length: 255, nullable: true)]
private ?string $comments = null;
#[ORM\ManyToOne]
#[ORM\JoinColumn(nullable: true)]
private ?SoftwareProfile $softwareProfile = null;
@ -55,6 +49,9 @@ class Image extends AbstractEntity
#[ORM\OneToMany(mappedBy: 'image', targetEntity: GitImageRepository::class,cascade: ['persist'], orphanRemoval: true)]
private Collection $gitImageRepositories;
#[ORM\Column(length: 255)]
private ?string $type = null;
public function __construct()
{
parent::__construct();
@ -62,30 +59,6 @@ class Image extends AbstractEntity
$this->gitImageRepositories = new ArrayCollection();
}
public function getDescription(): ?string
{
return $this->description;
}
public function setDescription(?string $description): static
{
$this->description = $description;
return $this;
}
public function getComments(): ?string
{
return $this->comments;
}
public function setComments(?string $comments): static
{
$this->comments = $comments;
return $this;
}
public function getSoftwareProfile(): ?SoftwareProfile
{
return $this->softwareProfile;
@ -243,4 +216,16 @@ class Image extends AbstractEntity
return $this;
}
public function getType(): ?string
{
return $this->type;
}
public function setType(string $type): static
{
$this->type = $type;
return $this;
}
}

View File

@ -35,7 +35,7 @@ class ImageRepository extends AbstractEntity
/**
* @var Collection<int, GitImageRepository>
*/
#[ORM\OneToMany(mappedBy: 'imageRepository', targetEntity: GitImageRepository::class)]
#[ORM\OneToMany(mappedBy: 'repository', targetEntity: GitImageRepository::class)]
private Collection $gitImageRepositories;
public function __construct()

View File

@ -0,0 +1,60 @@
<?php
namespace App\EventSubscriber;
use ApiPlatform\Symfony\EventListener\EventPriorities;
use App\Controller\OgBoot\PxeBootFile\PostAction;
use App\Dto\Output\CommandTaskScheduleOutput;
use App\Entity\CommandTaskSchedule;
use App\Entity\CommandTaskScript;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpKernel\Event\ViewEvent;
use Symfony\Component\HttpKernel\KernelEvents;
final readonly class CommandTaskScheduleSubscriber implements EventSubscriberInterface
{
public function __construct(
private EntityManagerInterface $entityManager,
)
{
}
public static function getSubscribedEvents(): array
{
return [
KernelEvents::VIEW => ['updateCommandTaskNextExecution', EventPriorities::POST_WRITE],
];
}
/**
* @throws \Exception
*/
public function updateCommandTaskNextExecution(ViewEvent $event): void
{
$commandTaskScheduleOutput = $event->getControllerResult();
$method = $event->getRequest()->getMethod();
if (!$commandTaskScheduleOutput instanceof CommandTaskScheduleOutput ||
!in_array($method, [Request::METHOD_POST, Request::METHOD_PUT, Request::METHOD_PATCH, Request::METHOD_DELETE])) {
return;
}
/** @var CommandTaskSchedule $commandTaskSchedule */
$commandTaskSchedule = $commandTaskScheduleOutput->getEntity();
$commandTask = $commandTaskSchedule->getCommandTask();
if ($commandTask === null) {
return;
}
$commandTask->setNextExecution($commandTask->calculateNextExecutionDate());
$this->entityManager->persist($commandTask);
$this->entityManager->flush();
}
}

View File

@ -0,0 +1,59 @@
<?php
namespace App\EventSubscriber;
use ApiPlatform\Symfony\EventListener\EventPriorities;
use App\Controller\OgBoot\PxeBootFile\PostAction;
use App\Dto\Output\CommandTaskScriptOutput;
use App\Entity\CommandTaskScript;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpKernel\Event\ViewEvent;
use Symfony\Component\HttpKernel\KernelEvents;
final readonly class CommandTaskScriptSubscriber implements EventSubscriberInterface
{
public function __construct(
private EntityManagerInterface $entityManager,
)
{
}
public static function getSubscribedEvents(): array
{
return [
KernelEvents::VIEW => ['updateCommandTaskNextExecution', EventPriorities::POST_WRITE],
];
}
/**
* @throws \Exception
*/
public function updateCommandTaskNextExecution(ViewEvent $event): void
{
$commandTaskScriptOutput = $event->getControllerResult();
$method = $event->getRequest()->getMethod();
if (!$commandTaskScriptOutput instanceof CommandTaskScriptOutput ||
!in_array($method, [Request::METHOD_POST, Request::METHOD_PUT, Request::METHOD_PATCH, Request::METHOD_DELETE])) {
return;
}
/** @var CommandTaskScript $commandTaskScript */
$commandTaskScript = $commandTaskScriptOutput->getEntity();
$commandTask = $commandTaskScript->getCommandTask();
if ($commandTask === null) {
return;
}
$commandTask->setNextExecution($commandTask->calculateNextExecutionDate());
$this->entityManager->persist($commandTask);
$this->entityManager->flush();
}
}

View File

@ -64,7 +64,7 @@ final readonly class OrganizationalUnitSubscriber implements EventSubscriberInte
$this->updateChildrenNetworkSettings($organizationalUnitEntity, $newNetworkSettings);
if ($organizationalUnitEntity->getType() === OrganizationalUnitTypes::CLASSROOM) {
//$this->syncOgBoot($organizationalUnitEntity);
$this->syncOgBoot($organizationalUnitEntity);
}
}

View File

@ -37,6 +37,7 @@ final class ImageFactory extends ModelFactory
'name' => self::faker()->text(255),
'softwareProfile' => SoftwareProfileFactory::new(),
'updatedAt' => self::faker()->dateTime(),
'type' => 'monolithic',
'remotePc' => self::faker()->boolean(),
'isGlobal' => false,
];

View File

@ -43,7 +43,7 @@ final class PartitionFactory extends ModelFactory
'updatedAt' => self::faker()->dateTime(),
'operativeSystem' => OperativeSystemFactory::new(),
'client' => ClientFactory::new(),
'image' => ImageFactory::new(),
'image' => ImageImageRepositoryFactory::new(),
];
}

View File

@ -3,6 +3,8 @@
namespace App\Repository;
use App\Entity\GitImageRepository;
use App\Entity\Image;
use App\Entity\ImageRepository as Repository;
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
use Doctrine\Persistence\ManagerRegistry;
@ -15,4 +17,17 @@ class GitImageRepositoryRepository extends AbstractRepository
{
parent::__construct($registry, GitImageRepository::class);
}
public function findLatestVersionByImageAndRepository(Image $image, Repository $repository): ?GitImageRepository
{
return $this->createQueryBuilder('i')
->andWhere('i.image = :imageId')
->setParameter('imageId', $image->getId())
->andWhere('i.repository = :repository')
->setParameter('repository', $repository->getId())
->orderBy('i.version', 'DESC')
->setMaxResults(1)
->getQuery()
->getOneOrNullResult();
}
}