balena-cli
Version:
The official balena Command Line Interface
129 lines • 4.65 kB
JavaScript
Object.defineProperty(exports, "__esModule", { value: true });
exports.deployLegacy = void 0;
const lazy_1 = require("./lazy");
const util_1 = require("util");
const getBuilderPushEndpoint = function (baseUrl, owner, app) {
const querystring = require('querystring');
const args = querystring.stringify({ owner, app });
return `https://builder.${baseUrl}/v1/push?${args}`;
};
const getBuilderLogPushEndpoint = function (baseUrl, buildId, owner, app) {
const querystring = require('querystring');
const args = querystring.stringify({ owner, app, buildId });
return `https://builder.${baseUrl}/v1/pushLogs?${args}`;
};
const bufferImage = function (docker, imageId, bufferFile) {
const streamUtils = require('./streams');
const image = docker.getImage(imageId);
const sizePromise = image.inspect().then((img) => img.Size);
return Promise.all([image.get(), sizePromise]).then(([imageStream, imageSize]) => streamUtils
.buffer(imageStream, bufferFile)
.then((bufferedStream) => {
bufferedStream.length = imageSize;
return bufferedStream;
}));
};
const showPushProgress = function (message) {
const visuals = (0, lazy_1.getVisuals)();
const progressBar = new visuals.Progress(message);
progressBar.update({ percentage: 0 });
return progressBar;
};
const uploadToPromise = (uploadRequest, logger) => new Promise(function (resolve, reject) {
uploadRequest.on('error', reject).on('data', function handleMessage(data) {
let obj;
data = data.toString();
logger.logDebug(`Received data: ${data}`);
try {
obj = JSON.parse(data);
}
catch (e) {
logger.logError('Error parsing reply from remote side');
reject(e);
return;
}
switch (obj.type) {
case 'error':
reject(new Error(`Remote error: ${obj.error}`));
break;
case 'success':
resolve(obj);
break;
case 'status':
logger.logInfo(obj.message);
break;
default:
reject(new Error(`Received unexpected reply from remote: ${data}`));
}
});
});
const uploadImage = function (imageStream, token, username, url, appName, logger) {
const request = require('request');
const progressStream = require('progress-stream');
const zlib = require('zlib');
const progressMessage = logger
.formatMessage('info', 'Uploading')
.slice(0, -1);
const progressBar = showPushProgress(progressMessage);
const streamWithProgress = imageStream.pipe(progressStream({
time: 500,
length: imageStream.length,
}, ({ percentage, eta }) => progressBar.update({
percentage: Math.min(percentage, 100),
eta,
})));
const uploadRequest = request.post({
url: getBuilderPushEndpoint(url, username, appName),
headers: {
'Content-Encoding': 'gzip',
},
auth: {
bearer: token,
},
body: streamWithProgress.pipe(zlib.createGzip({
level: 6,
})),
});
return uploadToPromise(uploadRequest, logger);
};
const uploadLogs = function (logs, token, url, buildId, username, appName) {
const request = require('request');
return request.post({
json: true,
url: getBuilderLogPushEndpoint(url, buildId, username, appName),
auth: {
bearer: token,
},
body: Buffer.from(logs),
});
};
const deployLegacy = async function (docker, logger, token, username, url, opts) {
const tmp = require('tmp');
const tmpNameAsync = (0, util_1.promisify)(tmp.tmpName);
tmp.setGracefulCleanup();
const { appName, imageName, buildLogs, shouldUploadLogs } = opts;
const logs = buildLogs;
const bufferFile = await tmpNameAsync();
logger.logInfo('Initializing deploy...');
const { buildId } = await bufferImage(docker, imageName, bufferFile)
.then((stream) => uploadImage(stream, token, username, url, appName, logger))
.finally(() => require('fs').promises
.unlink(bufferFile)
.catch(() => undefined));
if (shouldUploadLogs) {
logger.logInfo('Uploading logs...');
const args = await Promise.all([
logs,
token,
url,
buildId,
username,
appName,
]);
await uploadLogs(...args);
}
return buildId;
};
exports.deployLegacy = deployLegacy;
//# sourceMappingURL=deploy-legacy.js.map
;