@adpt/cloud
Version:
AdaptJS cloud component library
131 lines • 4.92 kB
JavaScript
"use strict";
/*
* Copyright 2019 Unbounded Systems, LLC
*
* 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 });
const core_1 = require("@adpt/core");
const lodash_1 = require("lodash");
const url_1 = require("url");
const util_1 = require("util");
const action_1 = require("../action");
function buildNameTag(url, nameTag) {
if (nameTag === undefined)
return undefined;
return `${url}/${nameTag}`;
}
function urlToRegistryString(registryUrl) {
let ret;
if (registryUrl.startsWith("http")) {
const parsed = new url_1.URL(registryUrl);
ret = parsed.host + parsed.pathname;
}
else {
ret = registryUrl;
}
if (ret.endsWith("/"))
ret = ret.slice(0, -1);
return ret;
}
function normalizeRegistryUrl(url) {
if (util_1.isString(url))
url = { external: url, internal: url };
return {
external: urlToRegistryString(url.external),
internal: urlToRegistryString(url.internal)
};
}
/**
* Represents a Docker image in a registry.
* @remarks
* If the image does not exist in the specified registry, it will be pushed
* to that registry.
* @public
*/
class RegistryDockerImage extends action_1.Action {
constructor(props) {
super(props);
/** @internal */
this.dependsOn = (_goalStatus, helpers) => {
if (!core_1.isHandle(this.props.imageSrc))
return undefined;
return helpers.dependsOn(this.props.imageSrc);
};
this.registry = normalizeRegistryUrl(props.registryUrl);
}
/**
* Returns information about the version of the Docker image that reflects
* the current set of props for the component and has been pushed to the
* registry.
* @remarks
* Returns undefined if the `props.imageSrc` component's `latestImage` method
* returns undefined (depending on the component referenced by
* `props.imageSrc`, that may indicate the source image has not been built).
* Also returns undefined if the current image has not yet been
* pushed to the registry.
*/
image() {
const srcImage = core_1.callInstanceMethod(this.props.imageSrc, undefined, "latestImage");
const latestImg = this.latestImage();
const latestReg = this.latestRegistryUrl_ || this.state.registryUrl;
if (!srcImage || !latestImg || !latestReg)
return undefined;
if (srcImage.id === latestImg.id &&
this.currentNameTag(srcImage.nameTag) === latestImg.nameTag &&
lodash_1.isEqual(this.registry, latestReg)) {
return latestImg;
}
return undefined; // Pushed image is not current
}
/**
* Returns information about the most current version of the Docker image
* that has been pushed to the registry.
* @remarks
* Returns undefined if no image has ever been pushed by this component.
*/
latestImage() { return this.latestImage_ || this.state.image; }
/** @internal */
initialState() { return {}; }
/** @internal */
shouldAct(diff) {
if (diff === core_1.ChangeType.delete)
return false;
let name = this.props.newTag || this.srcImageName();
name = name ? ` '${name}'` : "";
return { act: true, detail: `Pushing image${name} to ${this.registry.external}` };
}
/** @internal */
async action(op) {
if (op === core_1.ChangeType.delete || op === core_1.ChangeType.none)
return;
const info = await core_1.callInstanceMethod(this.props.imageSrc, undefined, "pushTo", this.registry.external, this.props.newTag);
if (info === undefined) {
throw new Error(`Image source component did not push image to registry`);
}
this.latestImage_ = Object.assign({}, info);
this.latestRegistryUrl_ = this.registry;
this.setState({
image: this.latestImage_,
registryUrl: this.latestRegistryUrl_,
});
}
currentNameTag(nameTag) {
return buildNameTag(this.registry.internal, this.props.newTag || nameTag);
}
srcImageName() {
return core_1.callFirstInstanceWithMethod(this.props.imageSrc, undefined, "displayName");
}
}
exports.RegistryDockerImage = RegistryDockerImage;
//# sourceMappingURL=RegistryDockerImage.js.map