mirror of
https://github.com/balena-io/balena-cli.git
synced 2025-02-06 11:10:10 +00:00
Convert lib/utils/deploy-legacy.coffee to javascript
Change-type: patch
This commit is contained in:
parent
a348528ed3
commit
203ccaf97b
@ -89,7 +89,7 @@ deployProject = (docker, logger, composeOpts, opts) ->
|
|||||||
}
|
}
|
||||||
.then (images) ->
|
.then (images) ->
|
||||||
if opts.app.application_type?[0]?.is_legacy
|
if opts.app.application_type?[0]?.is_legacy
|
||||||
legacyDeploy = require('../utils/deploy-legacy')
|
{ deployLegacy } = require('../utils/deploy-legacy')
|
||||||
|
|
||||||
msg = getChalk().yellow('Target application requires legacy deploy method.')
|
msg = getChalk().yellow('Target application requires legacy deploy method.')
|
||||||
logger.logWarn(msg)
|
logger.logWarn(msg)
|
||||||
@ -107,7 +107,7 @@ deployProject = (docker, logger, composeOpts, opts) ->
|
|||||||
buildLogs: images[0].logs
|
buildLogs: images[0].logs
|
||||||
shouldUploadLogs: opts.shouldUploadLogs
|
shouldUploadLogs: opts.shouldUploadLogs
|
||||||
}
|
}
|
||||||
legacyDeploy
|
deployLegacy
|
||||||
)
|
)
|
||||||
.then (releaseId) ->
|
.then (releaseId) ->
|
||||||
sdk.models.release.get(releaseId, $select: [ 'commit' ])
|
sdk.models.release.get(releaseId, $select: [ 'commit' ])
|
||||||
|
@ -1,137 +0,0 @@
|
|||||||
Promise = require('bluebird')
|
|
||||||
{ getVisuals } = require('./lazy')
|
|
||||||
|
|
||||||
getBuilderPushEndpoint = (baseUrl, owner, app) ->
|
|
||||||
querystring = require('querystring')
|
|
||||||
args = querystring.stringify({ owner, app })
|
|
||||||
"https://builder.#{baseUrl}/v1/push?#{args}"
|
|
||||||
|
|
||||||
getBuilderLogPushEndpoint = (baseUrl, buildId, owner, app) ->
|
|
||||||
querystring = require('querystring')
|
|
||||||
args = querystring.stringify({ owner, app, buildId })
|
|
||||||
"https://builder.#{baseUrl}/v1/pushLogs?#{args}"
|
|
||||||
|
|
||||||
bufferImage = (docker, imageId, bufferFile) ->
|
|
||||||
Promise = require('bluebird')
|
|
||||||
streamUtils = require('./streams')
|
|
||||||
|
|
||||||
image = docker.getImage(imageId)
|
|
||||||
imageMetadata = image.inspect()
|
|
||||||
|
|
||||||
Promise.join image.get(), imageMetadata.get('Size'), (imageStream, imageSize) ->
|
|
||||||
streamUtils.buffer(imageStream, bufferFile)
|
|
||||||
.tap (bufferedStream) ->
|
|
||||||
bufferedStream.length = imageSize
|
|
||||||
|
|
||||||
showPushProgress = (message) ->
|
|
||||||
visuals = getVisuals()
|
|
||||||
progressBar = new visuals.Progress(message)
|
|
||||||
progressBar.update({ percentage: 0 })
|
|
||||||
return progressBar
|
|
||||||
|
|
||||||
uploadToPromise = (uploadRequest, logger) ->
|
|
||||||
new Promise (resolve, reject) ->
|
|
||||||
|
|
||||||
handleMessage = (data) ->
|
|
||||||
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
|
|
||||||
when 'error' then reject(new Error("Remote error: #{obj.error}"))
|
|
||||||
when 'success' then resolve(obj)
|
|
||||||
when 'status' then logger.logInfo(obj.message)
|
|
||||||
else reject(new Error("Received unexpected reply from remote: #{data}"))
|
|
||||||
|
|
||||||
uploadRequest
|
|
||||||
.on('error', reject)
|
|
||||||
.on('data', handleMessage)
|
|
||||||
|
|
||||||
uploadImage = (imageStream, token, username, url, appName, logger) ->
|
|
||||||
request = require('request')
|
|
||||||
progressStream = require('progress-stream')
|
|
||||||
zlib = require('zlib')
|
|
||||||
|
|
||||||
# Need to strip off the newline
|
|
||||||
progressMessage = logger.formatMessage('info', 'Uploading').slice(0, -1)
|
|
||||||
progressBar = showPushProgress(progressMessage)
|
|
||||||
streamWithProgress = imageStream.pipe progressStream
|
|
||||||
time: 500,
|
|
||||||
length: imageStream.length
|
|
||||||
, ({ percentage, eta }) ->
|
|
||||||
progressBar.update
|
|
||||||
percentage: Math.min(percentage, 100)
|
|
||||||
eta: eta
|
|
||||||
|
|
||||||
uploadRequest = request.post
|
|
||||||
url: getBuilderPushEndpoint(url, username, appName)
|
|
||||||
headers:
|
|
||||||
'Content-Encoding': 'gzip'
|
|
||||||
auth:
|
|
||||||
bearer: token
|
|
||||||
body: streamWithProgress.pipe(zlib.createGzip({
|
|
||||||
level: 6
|
|
||||||
}))
|
|
||||||
|
|
||||||
uploadToPromise(uploadRequest, logger)
|
|
||||||
|
|
||||||
uploadLogs = (logs, token, url, buildId, username, appName) ->
|
|
||||||
request = require('request')
|
|
||||||
request.post
|
|
||||||
json: true
|
|
||||||
url: getBuilderLogPushEndpoint(url, buildId, username, appName)
|
|
||||||
auth:
|
|
||||||
bearer: token
|
|
||||||
body: Buffer.from(logs)
|
|
||||||
|
|
||||||
###
|
|
||||||
opts must be a hash with the following keys:
|
|
||||||
|
|
||||||
- appName: the name of the app to deploy to
|
|
||||||
- imageName: the name of the image to deploy
|
|
||||||
- buildLogs: a string with build output
|
|
||||||
- shouldUploadLogs
|
|
||||||
###
|
|
||||||
module.exports = (docker, logger, token, username, url, opts) ->
|
|
||||||
tmp = require('tmp')
|
|
||||||
tmpNameAsync = Promise.promisify(tmp.tmpName)
|
|
||||||
|
|
||||||
# Ensure the tmp files gets deleted
|
|
||||||
tmp.setGracefulCleanup()
|
|
||||||
|
|
||||||
{ appName, imageName, buildLogs, shouldUploadLogs } = opts
|
|
||||||
logs = buildLogs
|
|
||||||
|
|
||||||
tmpNameAsync()
|
|
||||||
.then (bufferFile) ->
|
|
||||||
logger.logInfo('Initializing deploy...')
|
|
||||||
bufferImage(docker, imageName, bufferFile)
|
|
||||||
.then (stream) ->
|
|
||||||
uploadImage(stream, token, username, url, appName, logger)
|
|
||||||
.finally ->
|
|
||||||
# If the file was never written to (for instance because an error
|
|
||||||
# has occured before any data was written) this call will throw an
|
|
||||||
# ugly error, just suppress it
|
|
||||||
Promise.try ->
|
|
||||||
require('mz/fs').unlink(bufferFile)
|
|
||||||
.catchReturn()
|
|
||||||
.tap ({ buildId }) ->
|
|
||||||
return if not shouldUploadLogs
|
|
||||||
|
|
||||||
logger.logInfo('Uploading logs...')
|
|
||||||
Promise.join(
|
|
||||||
logs
|
|
||||||
token
|
|
||||||
url
|
|
||||||
buildId
|
|
||||||
username
|
|
||||||
appName
|
|
||||||
uploadLogs
|
|
||||||
)
|
|
||||||
.get('buildId')
|
|
209
lib/utils/deploy-legacy.js
Normal file
209
lib/utils/deploy-legacy.js
Normal file
@ -0,0 +1,209 @@
|
|||||||
|
/**
|
||||||
|
* @license
|
||||||
|
* Copyright 2020 Balena Ltd.
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import * as Promise from 'bluebird';
|
||||||
|
import { getVisuals } from './lazy';
|
||||||
|
|
||||||
|
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 imageMetadata = image.inspect();
|
||||||
|
|
||||||
|
return Promise.join(
|
||||||
|
image.get(),
|
||||||
|
imageMetadata.get('Size'),
|
||||||
|
(imageStream, imageSize) =>
|
||||||
|
streamUtils.buffer(imageStream, bufferFile).tap(bufferedStream => {
|
||||||
|
// @ts-ignore adding an extra property
|
||||||
|
bufferedStream.length = imageSize;
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
const showPushProgress = function(message) {
|
||||||
|
const visuals = getVisuals();
|
||||||
|
const progressBar = new visuals.Progress(message);
|
||||||
|
progressBar.update({ percentage: 0 });
|
||||||
|
return progressBar;
|
||||||
|
};
|
||||||
|
|
||||||
|
const uploadToPromise = (uploadRequest, logger) =>
|
||||||
|
new Promise(function(resolve, reject) {
|
||||||
|
const handleMessage = function(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}`));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
uploadRequest.on('error', reject).on('data', handleMessage);
|
||||||
|
});
|
||||||
|
|
||||||
|
const uploadImage = function(
|
||||||
|
imageStream,
|
||||||
|
token,
|
||||||
|
username,
|
||||||
|
url,
|
||||||
|
appName,
|
||||||
|
logger,
|
||||||
|
) {
|
||||||
|
const request = require('request');
|
||||||
|
const progressStream = require('progress-stream');
|
||||||
|
const zlib = require('zlib');
|
||||||
|
|
||||||
|
// Need to strip off the newline
|
||||||
|
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),
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
opts must be a hash with the following keys:
|
||||||
|
|
||||||
|
- appName: the name of the app to deploy to
|
||||||
|
- imageName: the name of the image to deploy
|
||||||
|
- buildLogs: a string with build output
|
||||||
|
- shouldUploadLogs
|
||||||
|
*/
|
||||||
|
export const deployLegacy = function(
|
||||||
|
docker,
|
||||||
|
logger,
|
||||||
|
token,
|
||||||
|
username,
|
||||||
|
url,
|
||||||
|
opts,
|
||||||
|
) {
|
||||||
|
const tmp = require('tmp');
|
||||||
|
const tmpNameAsync = Promise.promisify(tmp.tmpName);
|
||||||
|
|
||||||
|
// Ensure the tmp files gets deleted
|
||||||
|
tmp.setGracefulCleanup();
|
||||||
|
|
||||||
|
const { appName, imageName, buildLogs, shouldUploadLogs } = opts;
|
||||||
|
const logs = buildLogs;
|
||||||
|
|
||||||
|
return tmpNameAsync()
|
||||||
|
.then(function(bufferFile) {
|
||||||
|
logger.logInfo('Initializing deploy...');
|
||||||
|
return bufferImage(docker, imageName, bufferFile)
|
||||||
|
.then(stream =>
|
||||||
|
uploadImage(stream, token, username, url, appName, logger),
|
||||||
|
)
|
||||||
|
.finally(() =>
|
||||||
|
// If the file was never written to (for instance because an error
|
||||||
|
// has occured before any data was written) this call will throw an
|
||||||
|
// ugly error, just suppress it
|
||||||
|
Promise.try(() => require('mz/fs').unlink(bufferFile)).catchReturn(
|
||||||
|
undefined,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
})
|
||||||
|
.tap(function({ buildId }) {
|
||||||
|
if (!shouldUploadLogs) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
logger.logInfo('Uploading logs...');
|
||||||
|
return Promise.join(
|
||||||
|
logs,
|
||||||
|
token,
|
||||||
|
url,
|
||||||
|
buildId,
|
||||||
|
username,
|
||||||
|
appName,
|
||||||
|
uploadLogs,
|
||||||
|
);
|
||||||
|
})
|
||||||
|
.get('buildId');
|
||||||
|
};
|
9
npm-shrinkwrap.json
generated
9
npm-shrinkwrap.json
generated
@ -1217,6 +1217,15 @@
|
|||||||
"integrity": "sha512-Zu4jAKE46yc6R8JrVkCBWbXhs18dUgI/JlbID4jziFgUBgEdAHxFekR5TlEnk9phHdGE80QlCznRBaxlk0rl7w==",
|
"integrity": "sha512-Zu4jAKE46yc6R8JrVkCBWbXhs18dUgI/JlbID4jziFgUBgEdAHxFekR5TlEnk9phHdGE80QlCznRBaxlk0rl7w==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"@types/progress-stream": {
|
||||||
|
"version": "2.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@types/progress-stream/-/progress-stream-2.0.0.tgz",
|
||||||
|
"integrity": "sha512-KKboL4BvIezEvnd2bdbIfIIkr3Th1p0AJOBaPdKMWm69uMoisOGd4mynzfB/iia2z0k3nwAJCmixESHfVjsrgw==",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"@types/node": "*"
|
||||||
|
}
|
||||||
|
},
|
||||||
"@types/range-parser": {
|
"@types/range-parser": {
|
||||||
"version": "1.2.3",
|
"version": "1.2.3",
|
||||||
"resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.3.tgz",
|
"resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.3.tgz",
|
||||||
|
@ -129,6 +129,7 @@
|
|||||||
"@types/node": "^10.17.20",
|
"@types/node": "^10.17.20",
|
||||||
"@types/node-cleanup": "^2.1.1",
|
"@types/node-cleanup": "^2.1.1",
|
||||||
"@types/prettyjson": "0.0.29",
|
"@types/prettyjson": "0.0.29",
|
||||||
|
"@types/progress-stream": "^2.0.0",
|
||||||
"@types/request": "^2.48.4",
|
"@types/request": "^2.48.4",
|
||||||
"@types/rewire": "^2.5.28",
|
"@types/rewire": "^2.5.28",
|
||||||
"@types/rimraf": "^2.0.4",
|
"@types/rimraf": "^2.0.4",
|
||||||
|
Loading…
x
Reference in New Issue
Block a user