UNPKG

@lxdhub/api

Version:

Display, search and copy LXD-images using a web interface.

123 lines (107 loc) 5.22 kB
import { Inject, NotFoundException } from '@nestjs/common'; import { CloneImageDto, CloneImageResponseDto, ImageDetailDto, ImageListItemDto } from '.'; import { PaginationOptionsDto, PaginationResponseDto, ResponseDto } from '../common'; import { LXDService } from '../lxd/lxd.service'; import { SearchDictionary, SearchService } from '../search'; import { ImageDetailFactory, ImageListItemFactory } from './factories'; import { ImageRepository } from './image.repository'; import { ImageSearchLiteral } from './interfaces'; import { RemoteService } from '../remote'; /** * Interface between the Database and API for * Image operations. */ export class ImageService { /** * Initialized the Image Service. * @param imageRepository The database interface for image operations * @param imageListItemFactory The api-image-interface * @param imageDetaiLFactory The api-image-detail-interface */ constructor( private readonly imageRepository: ImageRepository, private readonly imageListItemFactory: ImageListItemFactory, private readonly imageDetailFactory: ImageDetailFactory, private readonly searchService: SearchService, private readonly remoteService: RemoteService, @Inject('ImageSearchDictionary') private readonly imageSearchDictionary: SearchDictionary[], @Inject('LXDService') private readonly lxdService: LXDService, ) { } /** * Returns images, limited by the given pagination options, filtered * by the query parameter and transforms the database images into data-transfer-objects * @param remoteName The name of the remote * @param query The The query-string which filters the image. Search for image os name or arch Name * @param pagination The options to paginate through the request data */ async findByRemote(remoteName: string, pagination: PaginationOptionsDto, query?: string) : Promise<PaginationResponseDto<ImageListItemDto[]>> { const search: ImageSearchLiteral = query ? this.searchService.getLiteral(query, this.imageSearchDictionary, 'desc') : {}; const remote = await this.remoteService.findByName(remoteName); const [images, total] = await this.imageRepository.findByRemote(remote.id, pagination, search); // Return the custom pagination response, so the // data is wrapped around with metadata return new PaginationResponseDto<ImageListItemDto[]>( this.imageListItemFactory.entitiesToDto(images), total, pagination); } /** * Finds one image and returns detailed image information * in a DTO. * @param fingerprint The fingerprint of the image * @throws {Error} Will throw an error if the image is not found */ async findOne(fingerprint: string): Promise<ResponseDto<ImageDetailDto>> { // Fetch the image from the database const image = await this.imageRepository.findOneByFingerprint(fingerprint); // Map the data around a response and map the // database data to DTOs return new ResponseDto<ImageDetailDto>( this.imageDetailFactory.entityToDto(image) ); } /** * Clones an image to a specific remote * @param imageId The id of the image, which should get cloned * @param cloneImageDto The dto, which contains the remote information */ async cloneImage(imageId: number, cloneImageDto: CloneImageDto) : Promise<ResponseDto<CloneImageResponseDto>> { // Get image from database const image = await this.imageRepository.findOneItem(imageId); if (!image) throw new NotFoundException('Image not found'); const sourceRemote = await this.remoteService.findById(cloneImageDto.sourceRemoteId); if (!sourceRemote) throw new NotFoundException('Source Remote not found'); const destinationRemote = await this.remoteService.findById(cloneImageDto.destinationRemoteId); if (!destinationRemote) throw new NotFoundException('Destination Remote not found'); const uuid = await this.lxdService.cloneImage( image, sourceRemote, destinationRemote); return new ResponseDto<CloneImageResponseDto>({ uuid }); } /** * Imports and tags an image * @param remote The id of the image, which should get cloned * @param cloneImageDto The dto, which contains the remote information */ async importImage(image: any, remote: string, aliases: string[]) { if (!image) throw new NotFoundException('Image not found'); const fingerprint = await this.lxdService.importImage(remote, image); if (aliases) { if (!Array.isArray(aliases)) { // TODO: wtf js? aliases = [aliases]; } await this.lxdService.addImageAlias(remote, fingerprint, aliases, true); } // FIXME: add image to the database, this can't be done right now // because a big rework would be needed in order to do this in the // api comopnent, because much of the logic is in the dbsync component } }