@lxdhub/api
Version:
Display, search and copy LXD-images using a web interface.
167 lines • 7.38 kB
JavaScript
;
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