Merge pull request #639 from resin-io/628-add-progress-bars-for-resin-preload

Add progress bars and spinners for resin preload.
This commit is contained in:
Alexis Svinartchouk 2017-08-22 18:44:56 +02:00 committed by GitHub
commit 314fcd3919
4 changed files with 68 additions and 22 deletions

View File

@ -5,6 +5,7 @@ This project adheres to [Semantic Versioning](http://semver.org/).
### Changed
- Progress bar when preload builds its docker image or fetches the build size;
- Preload will do nothing if you try to preload a build that is already preloaded in the image.
## [6.5.1] - 2017-08-21

View File

@ -22,7 +22,9 @@ dockerUtils = require('../utils/docker');
LATEST = 'latest';
getApplicationsWithSuccessfulBuilds = function(resin, deviceType) {
getApplicationsWithSuccessfulBuilds = function(deviceType) {
var resin;
resin = require('resin-sdk-preconfigured');
return resin.pine.get({
resource: 'my_application',
options: {
@ -61,8 +63,15 @@ getApplicationsWithSuccessfulBuilds = function(resin, deviceType) {
});
};
selectApplication = function(expectedError, resin, form, deviceType) {
return getApplicationsWithSuccessfulBuilds(resin, deviceType).then(function(applications) {
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();
if (applications.length === 0) {
expectedError("You have no apps with successful builds for a '" + deviceType + "' device type.");
}
@ -79,8 +88,10 @@ selectApplication = function(expectedError, resin, form, deviceType) {
});
};
selectApplicationCommit = function(expectedError, resin, form, builds) {
var DEFAULT_CHOICE, choices;
selectApplicationCommit = function(builds) {
var DEFAULT_CHOICE, choices, expectedError, form;
form = require('resin-cli-form');
expectedError = require('../utils/patterns').expectedError;
if (builds.length === 0) {
expectedError('This application has no successful builds.');
}
@ -102,8 +113,11 @@ selectApplicationCommit = function(expectedError, resin, form, builds) {
});
};
offerToDisableAutomaticUpdates = function(Promise, form, resin, application, commit) {
var message;
offerToDisableAutomaticUpdates = function(application, commit) {
var Promise, form, message, resin;
Promise = require('bluebird');
resin = require('resin-sdk-preconfigured');
form = require('resin-cli-form');
if (commit === LATEST || !application.should_track_latest_release) {
return Promise.resolve();
}
@ -154,7 +168,7 @@ module.exports = {
}
]),
action: function(params, options, done) {
var Promise, _, errors, expectedError, form, preload, resin, streamToPromise;
var Promise, _, errors, expectedError, form, imageInfoSpinner, preload, resin, streamToPromise, visuals;
_ = require('lodash');
Promise = require('bluebird');
resin = require('resin-sdk-preconfigured');
@ -162,7 +176,9 @@ module.exports = {
form = require('resin-cli-form');
preload = require('resin-preload');
errors = require('resin-errors');
visuals = require('resin-cli-visuals');
expectedError = require('../utils/patterns').expectedError;
imageInfoSpinner = new visuals.Spinner('Reading image device type and preloaded builds.');
options.image = params.image;
options.appId = options.app;
delete options.app;
@ -171,19 +187,23 @@ module.exports = {
return dockerUtils.getDocker(options).then(function(docker) {
var buildOutputStream;
buildOutputStream = preload.build(docker);
buildOutputStream.pipe(process.stdout);
if (process.env.DEBUG) {
buildOutputStream.pipe(process.stdout);
}
return streamToPromise(buildOutputStream).then(resin.settings.getAll).then(function(settings) {
options.proxy = settings.proxy;
options.apiHost = settings.apiUrl;
imageInfoSpinner.start();
return preload.getDeviceTypeSlugAndPreloadedBuilds(docker, options)["catch"](preload.errors.ResinError, expectedError);
}).then(function(arg) {
var builds, slug;
slug = arg.slug, builds = arg.builds;
imageInfoSpinner.stop();
return Promise["try"](function() {
if (options.appId) {
return preload.getApplication(resin, options.appId)["catch"](errors.ResinApplicationNotFound, expectedError);
}
return selectApplication(expectedError, resin, form, slug);
return selectApplication(slug);
}).then(function(application) {
options.application = application;
if (slug !== application.device_type) {
@ -198,14 +218,14 @@ module.exports = {
}
return options.commit;
}
return selectApplicationCommit(expectedError, resin, form, application.build);
return selectApplicationCommit(application.build);
}).then(function(commit) {
if (commit === LATEST) {
options.commit = application.commit;
} else {
options.commit = commit;
}
return offerToDisableAutomaticUpdates(Promise, form, resin, application, commit);
return offerToDisableAutomaticUpdates(application, commit);
});
}).then(function() {
var ref;

View File

@ -18,7 +18,9 @@ dockerUtils = require('../utils/docker')
LATEST = 'latest'
getApplicationsWithSuccessfulBuilds = (resin, deviceType) ->
getApplicationsWithSuccessfulBuilds = (deviceType) ->
resin = require('resin-sdk-preconfigured')
resin.pine.get
resource: 'my_application'
options:
@ -50,9 +52,17 @@ getApplicationsWithSuccessfulBuilds = (resin, deviceType) ->
build.status == 'success'
applications
selectApplication = (expectedError, resin, form, deviceType) ->
getApplicationsWithSuccessfulBuilds(resin, deviceType)
selectApplication = (deviceType) ->
visuals = require('resin-cli-visuals')
form = require('resin-cli-form')
{ expectedError } = require('../utils/patterns')
applicationInfoSpinner = new visuals.Spinner('Downloading list of applications and builds.')
applicationInfoSpinner.start()
getApplicationsWithSuccessfulBuilds(deviceType)
.then (applications) ->
applicationInfoSpinner.stop()
if applications.length == 0
expectedError("You have no apps with successful builds for a '#{deviceType}' device type.")
form.ask
@ -62,7 +72,10 @@ selectApplication = (expectedError, resin, form, deviceType) ->
name: app.app_name
value: app
selectApplicationCommit = (expectedError, resin, form, builds) ->
selectApplicationCommit = (builds) ->
form = require('resin-cli-form')
{ expectedError } = require('../utils/patterns')
if builds.length == 0
expectedError('This application has no successful builds.')
DEFAULT_CHOICE = {'name': LATEST, 'value': LATEST}
@ -75,7 +88,11 @@ selectApplicationCommit = (expectedError, resin, form, builds) ->
default: LATEST
choices: choices
offerToDisableAutomaticUpdates = (Promise, form, resin, application, commit) ->
offerToDisableAutomaticUpdates = (application, commit) ->
Promise = require('bluebird')
resin = require('resin-sdk-preconfigured')
form = require('resin-cli-form')
if commit == LATEST or not application.should_track_latest_release
return Promise.resolve()
message = '''
@ -149,8 +166,11 @@ module.exports =
form = require('resin-cli-form')
preload = require('resin-preload')
errors = require('resin-errors')
visuals = require('resin-cli-visuals')
{ expectedError } = require('../utils/patterns')
imageInfoSpinner = new visuals.Spinner('Reading image device type and preloaded builds.')
options.image = params.image
options.appId = options.app
delete options.app
@ -164,7 +184,10 @@ module.exports =
# Build the preloader image
buildOutputStream = preload.build(docker)
buildOutputStream.pipe(process.stdout)
if process.env.DEBUG
buildOutputStream.pipe(process.stdout)
streamToPromise(buildOutputStream)
# Get resin sdk settings so we can pass them to the preloader
@ -174,15 +197,17 @@ module.exports =
options.apiHost = settings.apiUrl
# Use the preloader docker image to extract the deviceType of the image
imageInfoSpinner.start()
preload.getDeviceTypeSlugAndPreloadedBuilds(docker, options)
.catch(preload.errors.ResinError, expectedError)
.then ({ slug, builds }) ->
imageInfoSpinner.stop()
# Use the appId given as --app or show an interactive app selection menu
Promise.try ->
if options.appId
return preload.getApplication(resin, options.appId)
.catch(errors.ResinApplicationNotFound, expectedError)
selectApplication(expectedError, resin, form, slug)
selectApplication(slug)
.then (application) ->
options.application = application
@ -198,7 +223,7 @@ module.exports =
if not _.find(application.build, commit_hash: options.commit)
expectedError('There is no build matching this commit')
return options.commit
selectApplicationCommit(expectedError, resin, form, application.build)
selectApplicationCommit(application.build)
.then (commit) ->
# No commit specified => use the latest commit
@ -208,7 +233,7 @@ module.exports =
options.commit = commit
# Propose to disable automatic app updates if the commit is not the latest
offerToDisableAutomaticUpdates(Promise, form, resin, application, commit)
offerToDisableAutomaticUpdates(application, commit)
.then ->
builds = builds.map (build) ->

View File

@ -82,7 +82,7 @@
"resin-doodles": "0.0.1",
"resin-image-fs": "^2.3.0",
"resin-image-manager": "^4.1.1",
"resin-preload": "^3.0.0",
"resin-preload": "^3.1.0",
"resin-sdk-preconfigured": "^6.9.0",
"resin-settings-client": "^3.6.1",
"resin-stream-logger": "^0.0.4",