UNPKG

@lxdhub/api

Version:

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

167 lines 7.38 kB
"use strict"; var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) { var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; return c > 3 && r && Object.defineProperty(target, key, r), r; }; var __metadata = (this && this.__metadata) || function (k, v) { if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v); }; var __param = (this && this.__param) || function (paramIndex, decorator) { return function (target, key) { decorator(target, key, paramIndex); } }; Object.defineProperty(exports, "__esModule", { value: true }); const https_1 = require("https"); const common_1 = require("@nestjs/common"); const __1 = require(".."); const factories_1 = require("./factories"); const log_1 = require("../log"); const third_party_1 = require("../third-party"); let LXDService = class LXDService { constructor(axios, sourceImageFactory, settings) { this.axios = axios; this.sourceImageFactory = sourceImageFactory; this.settings = settings; this.logger = new log_1.LogService(this.constructor.name); } getAxiosHttpsInstance() { const options = { rejectUnauthorized: false }; if (this.settings.lxd) { if (this.settings.lxd.key) { options.key = this.settings.lxd.key; } if (this.settings.lxd.cert) { options.cert = this.settings.lxd.cert; } } return this.axios.create({ httpsAgent: new https_1.Agent(options) }); } /** * Requests a new image on the given remote * @param url The url to which the image should be request * @param sourceImageDto The image */ async requestNewImage(url, sourceImageDto) { const axios = this.getAxiosHttpsInstance(); return (await axios.post(url, sourceImageDto)).data; } /** * Waits for the given operation to end * @param url The operation url */ async waitForOperation(url) { const axios = this.getAxiosHttpsInstance(); return (await axios.get(url)).data; } /** * Clones the image from the given sourceRemote to the given destinationRemote * @param image The image to be cloned * @param sourceRemote The source remote, from which the images comes from * @param destinationRemote The destination Remote */ async cloneImage(image, sourceRemote, destinationRemote) { var _a, _b; const sourceImageDto = this.sourceImageFactory.entityToDto(image, sourceRemote, destinationRemote); const url = destinationRemote.serverUrl; // Start operation try { const operation = await this.requestNewImage(`${url}/1.0/images`, sourceImageDto); // The operation uuid return operation.metadata.id; } catch (err) { if (((_a = err) === null || _a === void 0 ? void 0 : _a.error_code) === 403) { throw new common_1.InternalServerErrorException('Server certificate is not valid. Contact a server administrator'); } if (((_b = err) === null || _b === void 0 ? void 0 : _b.error_code) === 500) { throw new common_1.InternalServerErrorException('The destination LXD remote is not reachable'); } throw err; } } /** * Waits for the clone operation and returns the result * @param destinationRemote The destination remote * @param operation The operation UUID from the LXD server */ async wait(remote, operation) { return await this.waitForOperation(`${remote}/1.0/operations/${operation}/wait`); } /** * Adds an image to a any given remote * @param image The image binary data * @param remote The remote to add the image to (format: https://localhost:8334) */ async importImage(remote, image) { var _a, _b, _c, _d; const axios = this.getAxiosHttpsInstance(); const { data: { operation } } = (await axios.post(`${remote}/1.0/images`, image.buffer, { headers: { 'X-LXD-Public': '1', }, maxContentLength: Infinity })); const result = (await axios.get(`${remote}/${operation}/wait`)).data; if (((_b = (_a = result) === null || _a === void 0 ? void 0 : _a.medatada) === null || _b === void 0 ? void 0 : _b.status) === 'Failure') { if ((_d = (_c = result.metadata) === null || _c === void 0 ? void 0 : _c.err, (_d !== null && _d !== void 0 ? _d : '')).includes('fingerprint already exists')) { // image already exists throw new common_1.ConflictException(result.metadata.err); } throw new common_1.InternalServerErrorException(result.metadata.err); } return result.metadata.metadata.fingerprint; } /** * Tags an image with some aliases * @param remote The remote to add the aliases to (format: https://localhost:8334) * @param fingerprint The SHA-fingerprint of the image to add the alias to * @param aliases The aliases to add * @param force Wether to overwrite already existing aliases */ async addImageAlias(remote, fingerprint, aliases, force = false) { const axios = this.getAxiosHttpsInstance(); const existingAliases = (await axios.get(`${remote}/1.0/images/aliases`)).data.metadata; const [newAliases, conflictingAliases] = [[], []]; for (const alias of aliases) { const exists = existingAliases.some((existingAlias) => existingAlias.endsWith(alias)); if (exists) { conflictingAliases.push(alias); } else { newAliases.push(alias); } } if (conflictingAliases.length) { if (!force) { throw new common_1.ConflictException(`Aliases ${conflictingAliases.join(',')} already exist`); } else { // overwrite aliases await Promise.all(conflictingAliases.map((alias) => axios.put(`${remote}/1.0/images/aliases/${alias}`, { description: `Alias ${alias} for ${fingerprint}`, target: fingerprint, }))); } } // add new aliases await Promise.all(newAliases.map((alias) => axios.post(`${remote}/1.0/images/aliases`, { description: `Alias ${alias} for ${fingerprint}`, target: fingerprint, name: alias }))); } }; LXDService = __decorate([ common_1.Injectable(), __param(0, common_1.Inject(third_party_1.AxiosToken)), __param(2, common_1.Inject('LXDHubAPISettings')), __metadata("design:paramtypes", [Object, factories_1.SourceImageFactory, __1.LXDHubAPISettings]) ], LXDService); exports.LXDService = LXDService; //# sourceMappingURL=lxd.service.js.map