2017-07-27 11:07:05 +00:00
// Generated by CoffeeScript 1.12.7
2017-06-28 16:30:50 +00:00
var Promise , dockerUtils , formatImageName , getBuilderLogPushEndpoint , getBuilderPushEndpoint , getBundleInfo , parseInput , performUpload , showPushProgress , uploadLogs , uploadToPromise ;
2017-03-29 11:03:40 +00:00
Promise = require ( 'bluebird' ) ;
2017-04-24 19:05:18 +00:00
dockerUtils = require ( '../utils/docker' ) ;
2017-03-29 11:03:40 +00:00
getBuilderPushEndpoint = function ( baseUrl , owner , app ) {
2017-04-24 10:06:53 +00:00
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 ;
2017-03-29 11:03:40 +00:00
} ;
formatImageName = function ( image ) {
return image . split ( '/' ) . pop ( ) ;
} ;
parseInput = Promise . method ( function ( params , options ) {
2017-04-24 14:55:54 +00:00
var appName , image , source ;
2017-03-29 11:03:40 +00:00
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 ) {
2017-04-24 14:55:54 +00:00
source = options . source || '.' ;
2017-03-29 11:03:40 +00:00
} else {
throw new Error ( 'Need either an image or a build flag!' ) ;
}
2017-04-24 14:55:54 +00:00
return [ appName , options . build , source , image ] ;
2017-03-29 11:03:40 +00:00
} ) ;
2017-06-28 16:57:49 +00:00
showPushProgress = function ( message ) {
2017-06-15 13:40:57 +00:00
var progressBar , visuals ;
visuals = require ( 'resin-cli-visuals' ) ;
2017-06-28 16:57:49 +00:00
progressBar = new visuals . Progress ( message ) ;
2017-06-15 13:40:57 +00:00
progressBar . update ( {
percentage : 0
} ) ;
return progressBar ;
2017-06-13 17:28:37 +00:00
} ;
2017-03-29 11:03:40 +00:00
getBundleInfo = function ( options ) {
var helpers ;
helpers = require ( '../utils/helpers' ) ;
return helpers . getAppInfo ( options . appName ) . then ( function ( app ) {
return [ app . arch , app . device _type ] ;
} ) ;
} ;
2017-06-28 16:30:37 +00:00
performUpload = function ( imageStream , token , username , url , appName , logger ) {
2017-06-28 16:57:49 +00:00
var progressBar , progressMessage , progressStream , request , streamWithProgress , uploadRequest , zlib ;
2017-03-29 11:03:40 +00:00
request = require ( 'request' ) ;
2017-06-13 17:28:37 +00:00
progressStream = require ( 'progress-stream' ) ;
zlib = require ( 'zlib' ) ;
2017-06-28 16:57:49 +00:00
progressMessage = logger . formatMessage ( 'info' , 'Deploying' ) . slice ( 0 , - 1 ) ;
progressBar = showPushProgress ( progressMessage ) ;
2017-06-13 17:28:37 +00:00
streamWithProgress = imageStream . pipe ( progressStream ( {
time : 500 ,
length : imageStream . length
} , function ( arg ) {
2017-06-15 13:40:57 +00:00
var eta , percentage ;
percentage = arg . percentage , eta = arg . eta ;
return progressBar . update ( {
percentage : Math . min ( percentage , 100 ) ,
eta : eta
} ) ;
2017-06-13 17:28:37 +00:00
} ) ) ;
2017-06-13 17:28:37 +00:00
uploadRequest = request . post ( {
2017-03-29 11:03:40 +00:00
url : getBuilderPushEndpoint ( url , username , appName ) ,
2017-06-13 17:28:37 +00:00
headers : {
'Content-Encoding' : 'gzip'
} ,
2017-03-29 11:03:40 +00:00
auth : {
bearer : token
} ,
2017-06-14 15:42:33 +00:00
body : streamWithProgress . pipe ( zlib . createGzip ( {
level : 6
} ) )
2017-03-29 11:03:40 +00:00
} ) ;
2017-06-28 16:30:37 +00:00
return uploadToPromise ( uploadRequest , logger ) ;
2017-03-29 11:03:40 +00:00
} ;
2017-04-24 10:06:53 +00:00
uploadLogs = function ( logs , token , url , buildId , username , appName ) {
var request ;
request = require ( 'request' ) ;
return request . post ( {
2017-04-28 12:44:40 +00:00
json : true ,
2017-04-24 10:06:53 +00:00
url : getBuilderLogPushEndpoint ( url , buildId , username , appName ) ,
auth : {
bearer : token
} ,
2017-04-28 12:44:40 +00:00
body : Buffer . from ( logs )
2017-04-24 10:06:53 +00:00
} ) ;
} ;
2017-06-28 16:30:37 +00:00
uploadToPromise = function ( uploadRequest , logger ) {
2017-03-29 11:03:40 +00:00
return new Promise ( function ( resolve , reject ) {
var handleMessage ;
handleMessage = function ( data ) {
2017-04-28 12:44:40 +00:00
var e , obj ;
2017-03-29 11:03:40 +00:00
data = data . toString ( ) ;
2017-06-28 16:30:37 +00:00
logger . logDebug ( "Received data: " + data ) ;
2017-04-28 12:44:40 +00:00
try {
2017-04-24 10:06:53 +00:00
obj = JSON . parse ( data ) ;
2017-04-28 12:44:40 +00:00
} catch ( error ) {
e = error ;
2017-06-28 16:30:37 +00:00
logger . logError ( 'Error parsing reply from remote side' ) ;
2017-04-28 12:44:40 +00:00
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' :
2017-06-28 16:30:37 +00:00
return logger . logInfo ( "Remote: " + obj . message ) ;
2017-04-28 12:44:40 +00:00
default :
return reject ( new Error ( "Received unexpected reply from remote: " + data ) ) ;
}
} else {
return reject ( new Error ( "Received unexpected reply from remote: " + data ) ) ;
}
2017-03-29 11:03:40 +00:00
} ;
2017-06-13 17:28:37 +00:00
return uploadRequest . on ( 'error' , reject ) . on ( 'data' , handleMessage ) ;
2017-03-29 11:03:40 +00:00
} ) ;
} ;
module . exports = {
signature : 'deploy <appName> [image]' ,
2017-06-13 17:45:48 +00:00
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 <appName> ([image] | --build [--source build-dir])\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' ,
2017-03-29 11:03:40 +00:00
permission : 'user' ,
2017-04-24 19:05:18 +00:00
options : dockerUtils . appendOptions ( [
2017-03-29 11:03:40 +00:00
{
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'
2017-04-24 10:06:53 +00:00
} , {
signature : 'nologupload' ,
description : "Don't upload build logs to the dashboard with image (if building)" ,
boolean : true
2017-03-29 11:03:40 +00:00
}
2017-04-24 19:05:18 +00:00
] ) ,
2017-03-29 11:03:40 +00:00
action : function ( params , options , done ) {
2017-06-28 16:30:37 +00:00
var Logger , _ , logger , logs , resin , tmp , tmpNameAsync , upload ;
2017-03-29 11:03:40 +00:00
_ = require ( 'lodash' ) ;
tmp = require ( 'tmp' ) ;
tmpNameAsync = Promise . promisify ( tmp . tmpName ) ;
resin = require ( 'resin-sdk-preconfigured' ) ;
2017-06-28 16:30:37 +00:00
Logger = require ( '../utils/logger' ) ;
logger = new Logger ( ) ;
2017-03-29 11:03:40 +00:00
tmp . setGracefulCleanup ( ) ;
2017-04-24 10:06:53 +00:00
logs = '' ;
upload = function ( token , username , url ) {
2017-06-20 10:48:15 +00:00
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
} ) ;
2017-06-14 10:26:16 +00:00
return Promise [ "try" ] ( function ( ) {
2017-06-20 10:48:15 +00:00
if ( build ) {
2017-06-28 16:30:37 +00:00
return dockerUtils . runBuild ( params , options , getBundleInfo , logger ) ;
2017-06-20 10:48:15 +00:00
} else {
return {
image : imageName ,
log : ''
} ;
}
} ) . then ( function ( arg1 ) {
var buildLogs , imageName ;
imageName = arg1 . image , buildLogs = arg1 . log ;
2017-06-28 16:30:37 +00:00
logger . logInfo ( 'Initializing deploy...' ) ;
2017-06-20 10:48:15 +00:00
logs = buildLogs ;
2017-06-28 16:30:37 +00:00
return Promise . all ( [ dockerUtils . bufferImage ( docker , imageName , bufferFile ) , token , username , url , params . appName , logger ] ) . spread ( performUpload ) ;
2017-06-20 10:48:15 +00:00
} ) [ "finally" ] ( function ( ) {
return Promise [ "try" ] ( function ( ) {
return require ( 'mz/fs' ) . unlink ( bufferFile ) ;
} ) [ "catch" ] ( _ . noop ) ;
} ) ;
2017-04-24 10:06:53 +00:00
} ) ;
2017-06-20 10:48:15 +00:00
} ) . tap ( function ( arg ) {
var buildId , imageName ;
imageName = arg . image , buildId = arg . buildId ;
2017-06-28 16:30:37 +00:00
logger . logSuccess ( "Successfully deployed image: " + ( formatImageName ( imageName ) ) ) ;
2017-06-20 10:48:15 +00:00
return buildId ;
} ) . then ( function ( arg ) {
var buildId , imageName ;
imageName = arg . image , buildId = arg . buildId ;
if ( logs === '' || ( options . nologupload != null ) ) {
return '' ;
}
2017-06-28 16:30:37 +00:00
logger . logInfo ( 'Uploading logs to dashboard...' ) ;
2017-06-20 10:48:15 +00:00
return Promise . join ( logs , token , url , buildId , username , params . appName , uploadLogs ) [ "return" ] ( 'Successfully uploaded logs' ) ;
} ) . then ( function ( msg ) {
if ( msg !== '' ) {
2017-06-28 16:30:37 +00:00
return logger . logSuccess ( msg ) ;
2017-06-20 10:48:15 +00:00
}
} ) . asCallback ( done ) ;
} ) ;
2017-04-24 10:06:53 +00:00
} ;
return Promise . join ( resin . auth . getToken ( ) , resin . auth . whoami ( ) , resin . settings . get ( 'resinUrl' ) , upload ) ;
2017-03-29 11:03:40 +00:00
}
} ;