@cto.ai/ops
Version:
š» CTO.ai Ops - The CLI built for Teams š
123 lines (122 loc) ⢠6.17 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
const tslib_1 = require("tslib");
const sdk_1 = require("@cto.ai/sdk");
const debug_1 = tslib_1.__importDefault(require("debug"));
const json = tslib_1.__importStar(require("JSONStream"));
const through = tslib_1.__importStar(require("through2"));
const CustomErrors_1 = require("../errors/CustomErrors");
const get_docker_1 = tslib_1.__importDefault(require("../utils/get-docker"));
const opConfig_1 = require("../constants/opConfig");
const env_1 = require("../constants/env");
const debug = debug_1.default('ops:PublishService');
class Publish {
constructor() {
this.publishOpToAPI = async (op, platformVersion, teamName, accessToken, api, isGlueCode = false) => {
try {
const res = await api.create(`/private/teams/${teamName}/ops`, Object.assign(Object.assign({}, op), { platformVersion, isGlueCode, isPublic: op.isPublic }), {
headers: {
Authorization: accessToken,
},
});
return res;
}
catch (err) {
debug('%O', err);
if (err.error[0].message === 'version is taken') {
throw new CustomErrors_1.VersionIsTaken();
}
throw new CustomErrors_1.CouldNotCreateOp(err.message);
}
};
this.publishOpToRegistry = async (apiOp, registryAuth, teamName, accessToken, registryAuthService, api, version) => {
const imageUniqueId = `${registryAuth.projectFullName}/${apiOp.id.toLowerCase()}:${apiOp.version}`;
const imageName = `${registryAuth.projectFullName}/${apiOp.name}:${apiOp.version}`;
const self = this;
const docker = await get_docker_1.default(self, 'publish');
try {
if (!docker) {
throw new Error('Could not initialize Docker.');
}
// getImage always returns an image. Must listImages
const image = docker.getImage(imageName);
if (!image) {
throw new CustomErrors_1.DockerPublishNoImageFound(apiOp.name, teamName);
}
console.log(`š Creating release ${sdk_1.ux.colors.callOutCyan(imageUniqueId)}... \n`);
const all = [];
const errors = [];
const seenChunks = {};
const parser = through.obj(function (chunk, _enc, cb) {
this.push(chunk.status);
if (chunk.errorDetail) {
debug(chunk.errorDetail);
errors.push(chunk.errorDetail.message);
}
else if (chunk.aux) {
console.log(`\nš ${sdk_1.ux.colors.white('Publishing...')}\n`);
console.log(`${sdk_1.ux.colors.green('>')} Tag: ${sdk_1.ux.colors.multiBlue(chunk.aux.Tag)}`);
console.log(`${sdk_1.ux.colors.green('>')} Size: ${sdk_1.ux.colors.multiBlue(chunk.aux.Size)}`);
console.log(`${sdk_1.ux.colors.green('>')} Digest: ${sdk_1.ux.colors.multiBlue(chunk.aux.Digest)}\n`);
}
else if (chunk.id) {
const chunkString = `${chunk.status}: ${sdk_1.ux.colors.white(chunk.id)}`;
if (!seenChunks[chunkString]) {
console.log(`${chunk.status}: ${sdk_1.ux.colors.white(chunk.id)}`);
seenChunks[chunkString] = true;
}
}
cb();
});
const _pipe = parser.pipe;
parser.pipe = function (dest) {
return _pipe(dest);
};
await new Promise(async function (resolve, reject) {
await image.tag({ repo: imageUniqueId }).catch(err => {
return reject(new CustomErrors_1.ImageTagError(err));
});
const taggedImage = docker.getImage(imageUniqueId);
const stream = await taggedImage
.push({
tag: apiOp.version,
authconfig: registryAuth.authconfig,
})
.catch(err => {
return reject(new CustomErrors_1.ImageTagError(err));
});
if (stream) {
stream
.pipe(json.parse())
.pipe(parser)
.on('data', (d) => {
all.push(d);
})
.on('end', async () => {
if (errors.length) {
return reject(new CustomErrors_1.ImagePushError(errors[0]));
}
console.log(`\nš ${sdk_1.ux.colors.callOutCyan(imageUniqueId)} has been published!`);
console.log(`š„ Visit your Op page here: ${sdk_1.ux.url(`${env_1.OPS_API_HOST}registry/${teamName}/${apiOp.name}`, `<${env_1.OPS_API_HOST}registry/${teamName}/${apiOp.name}>`)}\n`);
resolve();
});
}
});
}
catch (err) {
// this api service call will always return an error because it tries to
// remove the record from the api database and the harbor registry but
// no record in the harbor registry will exist
await api
.remove(`/private/${opConfig_1.getEndpointFromOpType(apiOp.type)}`, apiOp.id, {
headers: { Authorization: accessToken },
})
.catch(error => {
debug('%O', error);
});
throw err;
}
};
}
}
exports.Publish = Publish;