2017-08-04 12:53:31 +00:00
// Generated by CoffeeScript 1.12.7
/ *
Copyright 2016 - 2017 Resin . io
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 .
* /
2017-08-17 12:58:45 +00:00
var LATEST , dockerUtils , getApplicationsWithSuccessfulBuilds , offerToDisableAutomaticUpdates , selectApplication , selectApplicationCommit ,
indexOf = [ ] . indexOf || function ( item ) { for ( var i = 0 , l = this . length ; i < l ; i ++ ) { if ( i in this && this [ i ] === item ) return i ; } return - 1 ; } ;
2017-08-04 12:53:31 +00:00
dockerUtils = require ( '../utils/docker' ) ;
LATEST = 'latest' ;
2017-08-22 13:33:03 +00:00
getApplicationsWithSuccessfulBuilds = function ( deviceType ) {
2017-08-24 10:39:17 +00:00
var preload , resin ;
preload = require ( 'resin-preload' ) ;
2017-08-22 13:33:03 +00:00
resin = require ( 'resin-sdk-preconfigured' ) ;
2017-08-04 12:53:31 +00:00
return resin . pine . get ( {
resource : 'my_application' ,
options : {
filter : {
device _type : deviceType ,
build : {
$any : {
$alias : 'b' ,
$expr : {
b : {
status : 'success'
}
}
}
}
} ,
2017-08-24 10:39:17 +00:00
expand : preload . applicationExpandOptions ,
2017-08-04 12:53:31 +00:00
select : [ 'id' , 'app_name' , 'device_type' , 'commit' ] ,
orderby : 'app_name asc'
}
} ) ;
} ;
2017-08-22 13:33:03 +00:00
selectApplication = function ( deviceType ) {
var applicationInfoSpinner , expectedError , form , visuals ;
visuals = require ( 'resin-cli-visuals' ) ;
form = require ( 'resin-cli-form' ) ;
expectedError = require ( '../utils/patterns' ) . expectedError ;
applicationInfoSpinner = new visuals . Spinner ( 'Downloading list of applications and builds.' ) ;
applicationInfoSpinner . start ( ) ;
return getApplicationsWithSuccessfulBuilds ( deviceType ) . then ( function ( applications ) {
applicationInfoSpinner . stop ( ) ;
2017-08-04 12:53:31 +00:00
if ( applications . length === 0 ) {
expectedError ( "You have no apps with successful builds for a '" + deviceType + "' device type." ) ;
}
return form . ask ( {
message : 'Select an application' ,
type : 'list' ,
choices : applications . map ( function ( app ) {
return {
name : app . app _name ,
value : app
} ;
} )
} ) ;
} ) ;
} ;
2017-08-22 13:33:03 +00:00
selectApplicationCommit = function ( builds ) {
var DEFAULT _CHOICE , choices , expectedError , form ;
form = require ( 'resin-cli-form' ) ;
expectedError = require ( '../utils/patterns' ) . expectedError ;
2017-08-04 12:53:31 +00:00
if ( builds . length === 0 ) {
expectedError ( 'This application has no successful builds.' ) ;
}
DEFAULT _CHOICE = {
'name' : LATEST ,
'value' : LATEST
} ;
choices = [ DEFAULT _CHOICE ] . concat ( builds . map ( function ( build ) {
return {
name : build . push _timestamp + " - " + build . commit _hash ,
value : build . commit _hash
} ;
} ) ) ;
return form . ask ( {
message : 'Select a build' ,
type : 'list' ,
"default" : LATEST ,
choices : choices
} ) ;
} ;
2017-08-22 13:33:03 +00:00
offerToDisableAutomaticUpdates = function ( application , commit ) {
var Promise , form , message , resin ;
Promise = require ( 'bluebird' ) ;
resin = require ( 'resin-sdk-preconfigured' ) ;
form = require ( 'resin-cli-form' ) ;
2017-08-04 12:53:31 +00:00
if ( commit === LATEST || ! application . should _track _latest _release ) {
return Promise . resolve ( ) ;
}
message = '\nThis application is set to automatically update all devices to the latest available version.\nThis might be unexpected behaviour: with this enabled, the preloaded device will still\ndownload and install the latest build once it is online.\n\nDo you want to disable automatic updates for this application?' ;
return form . ask ( {
message : message ,
type : 'confirm'
} ) . then ( function ( update ) {
if ( ! update ) {
return ;
}
return resin . pine . patch ( {
resource : 'application' ,
id : application . id ,
body : {
should _track _latest _release : false
}
} ) ;
} ) ;
} ;
module . exports = {
signature : 'preload <image>' ,
2017-10-06 09:05:24 +00:00
description : '(beta) preload an app on a disk image (or Edison zip archive)' ,
help : 'Warning: "resin preload" requires Docker to be correctly installed in\nyour shell environment. For more information (including Windows support)\nplease check the README here: https://github.com/resin-io/resin-cli .\n\nUse this command to preload an application to a local disk image (or\nEdison zip archive) with a built commit from Resin.io.\nThis can be used with cloud builds, or images deployed with resin deploy.\n\nExamples:\n $ resin preload resin.img --app 1234 --commit e1f2592fc6ee949e68756d4f4a48e49bff8d72a0 --splash-image some-image.png\n $ resin preload resin.img' ,
2017-08-04 12:53:31 +00:00
permission : 'user' ,
primary : true ,
options : dockerUtils . appendConnectionOptions ( [
{
signature : 'app' ,
parameter : 'appId' ,
description : 'id of the application to preload' ,
alias : 'a'
} , {
signature : 'commit' ,
parameter : 'hash' ,
description : 'a specific application commit to preload (ignored if no appId is given)' ,
alias : 'c'
} , {
signature : 'splash-image' ,
parameter : 'splashImage.png' ,
description : 'path to a png image to replace the splash screen' ,
alias : 's'
} , {
signature : 'dont-detect-flasher-type-images' ,
boolean : true ,
description : 'Disables the flasher type images detection: treats all images as non flasher types'
2017-08-25 10:27:38 +00:00
} , {
signature : 'dont-check-device-type' ,
boolean : true ,
description : 'Disables check for matching device types in image and application'
2017-08-04 12:53:31 +00:00
}
] ) ,
action : function ( params , options , done ) {
2017-10-06 09:05:24 +00:00
var Promise , _ , errors , expectedError , form , nodeCleanup , preload , progressBars , progressHandler , resin , spinnerHandler , spinners , streamToPromise , visuals ;
2017-08-04 12:53:31 +00:00
_ = require ( 'lodash' ) ;
Promise = require ( 'bluebird' ) ;
resin = require ( 'resin-sdk-preconfigured' ) ;
streamToPromise = require ( 'stream-to-promise' ) ;
form = require ( 'resin-cli-form' ) ;
preload = require ( 'resin-preload' ) ;
errors = require ( 'resin-errors' ) ;
2017-08-22 13:33:03 +00:00
visuals = require ( 'resin-cli-visuals' ) ;
2017-10-06 09:05:24 +00:00
nodeCleanup = require ( 'node-cleanup' ) ;
2017-08-04 12:53:31 +00:00
expectedError = require ( '../utils/patterns' ) . expectedError ;
2017-10-06 09:05:24 +00:00
progressBars = { } ;
progressHandler = function ( event ) {
var progressBar ;
progressBar = progressBars [ event . name ] ;
if ( ! progressBar ) {
progressBar = progressBars [ event . name ] = new visuals . Progress ( event . name ) ;
}
return progressBar . update ( {
percentage : event . percentage
} ) ;
} ;
spinners = { } ;
spinnerHandler = function ( event ) {
var spinner ;
spinner = spinners [ event . name ] ;
if ( ! spinner ) {
spinner = spinners [ event . name ] = new visuals . Spinner ( event . name ) ;
}
if ( event . action === 'start' ) {
return spinner . start ( ) ;
} else {
console . log ( ) ;
return spinner . stop ( ) ;
}
} ;
2017-08-04 12:53:31 +00:00
options . image = params . image ;
options . appId = options . app ;
delete options . app ;
options . dontDetectFlasherTypeImages = options [ 'dont-detect-flasher-type-images' ] ;
delete options [ 'dont-detect-flasher-type-images' ] ;
2017-10-06 09:14:46 +00:00
options . splashImage = options [ 'splash-image' ] ;
delete options [ 'splash-image' ] ;
2017-10-06 09:05:24 +00:00
if ( options [ 'dont-check-device-type' ] && ! options . appId ) {
expectedError ( 'You need to specify an app id if you disable the device type check.' ) ;
}
2017-08-04 12:53:31 +00:00
return dockerUtils . getDocker ( options ) . then ( function ( docker ) {
2017-10-06 09:05:24 +00:00
var gotSignal , preloader ;
preloader = new preload . Preloader ( resin , docker , options . appId , options . commit , options . image , options . splashImage , options . proxy , options . dontDetectFlasherTypeImages ) ;
gotSignal = false ;
nodeCleanup ( function ( exitCode , signal ) {
if ( signal ) {
gotSignal = true ;
nodeCleanup . uninstall ( ) ;
preloader . cleanup ( ) . then ( function ( ) {
return process . kill ( process . pid , signal ) ;
} ) ;
return false ;
}
} ) ;
2017-08-22 13:33:03 +00:00
if ( process . env . DEBUG ) {
2017-10-06 09:05:24 +00:00
preloader . stderr . pipe ( process . stderr ) ;
2017-08-22 13:33:03 +00:00
}
2017-10-06 09:05:24 +00:00
preloader . on ( 'progress' , progressHandler ) ;
preloader . on ( 'spinner' , spinnerHandler ) ;
return new Promise ( function ( resolve , reject ) {
preloader . on ( 'error' , reject ) ;
return preloader . build ( ) . then ( function ( ) {
return preloader . prepare ( ) ;
} ) . then ( function ( ) {
return preloader . getDeviceTypeAndPreloadedBuilds ( ) ;
} ) . then ( function ( info ) {
2017-08-04 12:53:31 +00:00
return Promise [ "try" ] ( function ( ) {
2017-10-06 09:05:24 +00:00
if ( options . appId ) {
return preloader . fetchApplication ( ) [ "catch" ] ( errors . ResinApplicationNotFound , expectedError ) ;
2017-08-04 12:53:31 +00:00
}
2017-10-06 09:05:24 +00:00
return selectApplication ( info . device _type ) ;
} ) . then ( function ( application ) {
preloader . setApplication ( application ) ;
if ( info . device _type !== application . device _type ) {
expectedError ( "Image device type (" + application . device _type + ") and application device type (" + slug + ") do not match" ) ;
2017-08-04 12:53:31 +00:00
}
2017-10-06 09:05:24 +00:00
return Promise [ "try" ] ( function ( ) {
if ( options . commit ) {
if ( ! _ . find ( application . build , {
commit _hash : options . commit
} ) ) {
expectedError ( 'There is no build matching this commit' ) ;
}
return options . commit ;
}
return selectApplicationCommit ( application . build ) ;
} ) . then ( function ( commit ) {
if ( commit === LATEST ) {
preloader . commit = application . commit ;
} else {
preloader . commit = commit ;
}
return offerToDisableAutomaticUpdates ( application , commit ) ;
} ) ;
} ) . then ( function ( ) {
var builds , ref ;
builds = info . preloaded _builds . map ( function ( build ) {
return build . slice ( - preload . BUILD _HASH _LENGTH ) ;
} ) ;
if ( ref = preloader . commit , indexOf . call ( builds , ref ) >= 0 ) {
throw new preload . errors . ResinError ( 'This build is already preloaded in this image.' ) ;
}
return preloader . preload ( ) [ "catch" ] ( preload . errors . ResinError , expectedError ) ;
2017-08-17 12:58:45 +00:00
} ) ;
2017-10-06 09:05:24 +00:00
} ) . then ( resolve ) [ "catch" ] ( reject ) ;
} ) . then ( done ) [ "finally" ] ( function ( ) {
if ( ! gotSignal ) {
return preloader . cleanup ( ) ;
}
2017-08-04 12:53:31 +00:00
} ) ;
2017-10-06 09:05:24 +00:00
} ) ;
2017-08-04 12:53:31 +00:00
}
} ;