UNPKG

etcher-sdk

Version:
151 lines 5.29 kB
"use strict"; /* * Copyright 2018 balena.io * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ Object.defineProperty(exports, "__esModule", { value: true }); exports.BalenaS3Source = exports.BalenaS3SourceBase = void 0; const aws4_axios_1 = require("aws4-axios"); const axios_1 = require("axios"); const http_1 = require("./http"); const source_destination_1 = require("./source-destination"); const zip_1 = require("./zip"); const ESR_IMAGES_PREFIX = 'esr-images'; const IMAGES_PREFIX = 'images'; const PRELOADED_IMAGES_PREFIX = 'preloaded-images'; class BalenaS3SourceBase extends source_destination_1.SourceDestination { constructor({ host, bucket, prefix, deviceType, buildId, release, imageType, awsCredentials, }) { super(); this.host = host; this.bucket = bucket; if (prefix !== undefined) { this.prefix = prefix; } else if (release !== undefined) { this.prefix = PRELOADED_IMAGES_PREFIX; } else if (BalenaS3SourceBase.isESRVersion(buildId)) { this.prefix = ESR_IMAGES_PREFIX; } else { this.prefix = IMAGES_PREFIX; } this.deviceType = deviceType; this.buildId = buildId; this.release = release; this.imageType = imageType; this.axiosInstance = axios_1.default.create(); if (awsCredentials !== undefined) { this.axiosInstance.interceptors.request.use((0, aws4_axios_1.aws4Interceptor)({ options: { service: 's3' }, credentials: awsCredentials, })); } } get imageSuffix() { return this.imageType ? `-${this.imageType}` : ''; } async canCreateReadStream() { return true; } static isESRVersion(buildId) { return /^\d{4}\.\d{1,2}\.\d+([.+](dev|prod))?$/.test(buildId); } isESR() { return BalenaS3SourceBase.isESRVersion(this.buildId); } async download(path, responseType) { return await this.axiosInstance.get(this.getUrl(path), { responseType }); } getUrl(path) { let prefix = this.prefix; let release = this.release; // Preloaded images have no VERSION, VERSION_HOSTOS or device-type.json file, we need to get it from the images or esr-images folder if (release !== undefined && BalenaS3SourceBase.filesMissingFromPreloadedImages.includes(path)) { release = undefined; prefix = this.isESR() ? ESR_IMAGES_PREFIX : IMAGES_PREFIX; } return [ this.host, this.bucket, prefix, this.deviceType, encodeURIComponent(this.buildId), release, path, ] .filter((x) => x !== undefined) .join('/'); } } exports.BalenaS3SourceBase = BalenaS3SourceBase; BalenaS3SourceBase.filesMissingFromPreloadedImages = [ 'VERSION', 'VERSION_HOSTOS', 'device-type.json', ]; class BalenaS3Source extends BalenaS3SourceBase { constructor() { super(...arguments); this.names = ['balena', 'resin']; } async getName() { for (const name of this.names) { try { await this.axiosInstance({ method: 'head', url: this.getUrl(`image/${name}${this.imageSuffix}.img`), }); return name; } catch (error) { if (error.response.status !== 404) { throw error; } } } throw new Error('Could not find image'); } async canRead() { return true; } async read(buffer, bufferOffset, length, sourceOffset) { return await this.rawSource.read(buffer, bufferOffset, length, sourceOffset); } async createReadStream(options = {}) { return await this.zipSource.createReadStream(options); } async _getMetadata() { return await this.zipSource.getMetadata(); } async _open() { this.name = await this.getName(); this.rawSource = new http_1.Http({ url: this.getUrl(`image/${this.name}.img`), axiosInstance: this.axiosInstance, }); this.zipSource = new zip_1.ZipSource(new http_1.Http({ url: this.getUrl(`image/${this.name}.img.zip`), avoidRandomAccess: true, axiosInstance: this.axiosInstance, })); await Promise.all([this.rawSource.open(), await this.zipSource.open()]); } async _close() { await Promise.all([this.zipSource.close(), await this.rawSource.close()]); } } exports.BalenaS3Source = BalenaS3Source; //# sourceMappingURL=balena-s3-source.js.map