// Generated by CoffeeScript 1.12.7 var Promise, dockerUtils, formatImageName, getBuilderLogPushEndpoint, getBuilderPushEndpoint, getBundleInfo, parseInput, performUpload, showPushProgress, uploadLogs, uploadToPromise; Promise = require('bluebird'); dockerUtils = require('../utils/docker'); getBuilderPushEndpoint = function(baseUrl, owner, app) { var args, querystring; querystring = require('querystring'); args = querystring.stringify({ owner: owner, app: app }); return "https://builder." + baseUrl + "/v1/push?" + args; }; getBuilderLogPushEndpoint = function(baseUrl, buildId, owner, app) { var args, querystring; querystring = require('querystring'); args = querystring.stringify({ owner: owner, app: app, buildId: buildId }); return "https://builder." + baseUrl + "/v1/pushLogs?" + args; }; formatImageName = function(image) { return image.split('/').pop(); }; parseInput = Promise.method(function(params, options) { var appName, image, source; if (params.appName == null) { throw new Error('Need an application to deploy to!'); } appName = params.appName; image = void 0; if (params.image != null) { if (options.build || (options.source != null)) { throw new Error('Build and source parameters are not applicable when specifying an image'); } options.build = false; image = params.image; } else if (options.build) { source = options.source || '.'; } else { throw new Error('Need either an image or a build flag!'); } return [appName, options.build, source, image]; }); showPushProgress = function(message) { var progressBar, visuals; visuals = require('resin-cli-visuals'); progressBar = new visuals.Progress(message); progressBar.update({ percentage: 0 }); return progressBar; }; getBundleInfo = function(options) { var helpers; helpers = require('../utils/helpers'); return helpers.getAppInfo(options.appName).then(function(app) { return [app.arch, app.device_type]; }); }; performUpload = function(imageStream, token, username, url, appName, logger) { var progressBar, progressMessage, progressStream, request, streamWithProgress, uploadRequest, zlib; request = require('request'); progressStream = require('progress-stream'); zlib = require('zlib'); progressMessage = logger.formatMessage('info', 'Deploying').slice(0, -1); progressBar = showPushProgress(progressMessage); streamWithProgress = imageStream.pipe(progressStream({ time: 500, length: imageStream.length }, function(arg) { var eta, percentage; percentage = arg.percentage, eta = arg.eta; return 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 })) }); return uploadToPromise(uploadRequest, logger); }; uploadLogs = function(logs, token, url, buildId, username, appName) { var request; request = require('request'); return request.post({ json: true, url: getBuilderLogPushEndpoint(url, buildId, username, appName), auth: { bearer: token }, body: Buffer.from(logs) }); }; uploadToPromise = function(uploadRequest, logger) { return new Promise(function(resolve, reject) { var handleMessage; handleMessage = function(data) { var e, obj; data = data.toString(); logger.logDebug("Received data: " + data); try { obj = JSON.parse(data); } catch (error) { e = error; logger.logError('Error parsing reply from remote side'); reject(e); return; } if (obj.type != null) { switch (obj.type) { case 'error': return reject(new Error("Remote error: " + obj.error)); case 'success': return resolve(obj); case 'status': return logger.logInfo("Remote: " + obj.message); default: return reject(new Error("Received unexpected reply from remote: " + data)); } } else { return reject(new Error("Received unexpected reply from remote: " + data)); } }; return uploadRequest.on('error', reject).on('data', handleMessage); }); }; module.exports = { signature: 'deploy [image]', description: 'Deploy an image to a resin.io application', help: 'Use this command to deploy an image to an application, optionally building it first.\n\nUsage: `deploy ([image] | --build [--source build-dir])`\n\nTo deploy to an app on which you\'re a collaborator, use\n`resin deploy /`.\n\nNote: If building with this command, all options supported by `resin build`\nare also supported with this command.\n\nExamples:\n $ resin deploy myApp --build --source myBuildDir/\n $ resin deploy myApp myApp/myImage', permission: 'user', options: dockerUtils.appendOptions([ { signature: 'build', boolean: true, description: 'Build image then deploy', alias: 'b' }, { signature: 'source', parameter: 'source', description: 'The source directory to use when building the image', alias: 's' }, { signature: 'nologupload', description: "Don't upload build logs to the dashboard with image (if building)", boolean: true } ]), action: function(params, options, done) { var Logger, _, logger, logs, resin, tmp, tmpNameAsync, upload; _ = require('lodash'); tmp = require('tmp'); tmpNameAsync = Promise.promisify(tmp.tmpName); resin = require('resin-sdk-preconfigured'); Logger = require('../utils/logger'); logger = new Logger(); tmp.setGracefulCleanup(); logs = ''; upload = function(token, username, url) { return dockerUtils.getDocker(options).then(function(docker) { return parseInput(params, options).then(function(arg) { var appName, build, imageName, source; appName = arg[0], build = arg[1], source = arg[2], imageName = arg[3]; return tmpNameAsync().then(function(bufferFile) { options = _.assign({}, options, { appName: appName }); params = _.assign({}, params, { source: source }); return Promise["try"](function() { if (build) { return dockerUtils.runBuild(params, options, getBundleInfo, logger); } else { return { image: imageName, log: '' }; } }).then(function(arg1) { var buildLogs, imageName; imageName = arg1.image, buildLogs = arg1.log; logger.logInfo('Initializing deploy...'); logs = buildLogs; return Promise.all([dockerUtils.bufferImage(docker, imageName, bufferFile), token, username, url, params.appName, logger]).spread(performUpload); })["finally"](function() { return Promise["try"](function() { return require('mz/fs').unlink(bufferFile); })["catch"](_.noop); }); }); }).tap(function(arg) { var buildId, imageName; imageName = arg.image, buildId = arg.buildId; logger.logSuccess("Successfully deployed image: " + (formatImageName(imageName))); return buildId; }).then(function(arg) { var buildId, imageName; imageName = arg.image, buildId = arg.buildId; if (logs === '' || (options.nologupload != null)) { return ''; } logger.logInfo('Uploading logs to dashboard...'); return Promise.join(logs, token, url, buildId, username, params.appName, uploadLogs)["return"]('Successfully uploaded logs'); }).then(function(msg) { if (msg !== '') { return logger.logSuccess(msg); } }).asCallback(done); }); }; return Promise.join(resin.auth.getToken(), resin.auth.whoami(), resin.settings.get('resinUrl'), upload); } };