mirror of
https://github.com/balena-io/balena-cli.git
synced 2025-01-18 02:39:49 +00:00
Update resin-preload to 4.0.2 to support preloading Edison images
Change-Type: patch
This commit is contained in:
parent
dad655c9ec
commit
119fa78927
@ -127,8 +127,8 @@ offerToDisableAutomaticUpdates = function(application, commit) {
|
||||
|
||||
module.exports = {
|
||||
signature: 'preload <image>',
|
||||
description: '(beta) preload an app on a disk image',
|
||||
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 with a\nbuilt 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',
|
||||
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',
|
||||
permission: 'user',
|
||||
primary: true,
|
||||
options: dockerUtils.appendConnectionOptions([
|
||||
@ -158,7 +158,7 @@ module.exports = {
|
||||
}
|
||||
]),
|
||||
action: function(params, options, done) {
|
||||
var Promise, _, errors, expectedError, form, imageInfoSpinner, preload, resin, streamToPromise, visuals;
|
||||
var Promise, _, errors, expectedError, form, nodeCleanup, preload, progressBars, progressHandler, resin, spinnerHandler, spinners, streamToPromise, visuals;
|
||||
_ = require('lodash');
|
||||
Promise = require('bluebird');
|
||||
resin = require('resin-sdk-preconfigured');
|
||||
@ -167,8 +167,33 @@ module.exports = {
|
||||
preload = require('resin-preload');
|
||||
errors = require('resin-errors');
|
||||
visuals = require('resin-cli-visuals');
|
||||
nodeCleanup = require('node-cleanup');
|
||||
expectedError = require('../utils/patterns').expectedError;
|
||||
imageInfoSpinner = new visuals.Spinner('Reading image device type and preloaded builds.');
|
||||
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();
|
||||
}
|
||||
};
|
||||
options.image = params.image;
|
||||
options.appId = options.app;
|
||||
delete options.app;
|
||||
@ -176,72 +201,79 @@ module.exports = {
|
||||
delete options['dont-detect-flasher-type-images'];
|
||||
options.splashImage = options['splash-image'];
|
||||
delete options['splash-image'];
|
||||
if (options['dont-check-device-type'] && !options.appId) {
|
||||
expectedError('You need to specify an app id if you disable the device type check.');
|
||||
}
|
||||
return dockerUtils.getDocker(options).then(function(docker) {
|
||||
var buildOutputStream;
|
||||
buildOutputStream = preload.build(docker);
|
||||
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['dont-check-device-type'] && !options.appId) {
|
||||
expectedError('You need to specify an app id if you disable the device type check.');
|
||||
}
|
||||
if (options.appId) {
|
||||
return preload.getApplication(resin, options.appId)["catch"](errors.ResinApplicationNotFound, expectedError);
|
||||
}
|
||||
return selectApplication(slug);
|
||||
}).then(function(application) {
|
||||
options.application = application;
|
||||
if (slug !== application.device_type) {
|
||||
expectedError("Image device type (" + application.device_type + ") and application device type (" + slug + ") do not match");
|
||||
}
|
||||
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) {
|
||||
options.commit = application.commit;
|
||||
} else {
|
||||
options.commit = commit;
|
||||
}
|
||||
return offerToDisableAutomaticUpdates(application, commit);
|
||||
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);
|
||||
});
|
||||
}).then(function() {
|
||||
var ref;
|
||||
builds = builds.map(function(build) {
|
||||
return build.slice(-preload.BUILD_HASH_LENGTH);
|
||||
});
|
||||
if (ref = options.commit, indexOf.call(builds, ref) >= 0) {
|
||||
console.log('This build is already preloaded in this image.');
|
||||
process.exit(0);
|
||||
}
|
||||
return preload.run(resin, docker, options)["catch"](preload.errors.ResinError, expectedError);
|
||||
});
|
||||
return false;
|
||||
}
|
||||
});
|
||||
}).then(function(info) {
|
||||
info.stdout.pipe(process.stdout);
|
||||
info.stderr.pipe(process.stderr);
|
||||
return info.statusCodePromise;
|
||||
}).then(function(statusCode) {
|
||||
if (statusCode !== 0) {
|
||||
return process.exit(statusCode);
|
||||
if (process.env.DEBUG) {
|
||||
preloader.stderr.pipe(process.stderr);
|
||||
}
|
||||
}).then(done);
|
||||
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) {
|
||||
return Promise["try"](function() {
|
||||
if (options.appId) {
|
||||
return preloader.fetchApplication()["catch"](errors.ResinApplicationNotFound, expectedError);
|
||||
}
|
||||
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");
|
||||
}
|
||||
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);
|
||||
});
|
||||
}).then(resolve)["catch"](reject);
|
||||
}).then(done)["finally"](function() {
|
||||
if (!gotSignal) {
|
||||
return preloader.cleanup();
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
};
|
||||
|
@ -102,14 +102,14 @@ offerToDisableAutomaticUpdates = (application, commit) ->
|
||||
|
||||
module.exports =
|
||||
signature: 'preload <image>'
|
||||
description: '(beta) preload an app on a disk image'
|
||||
description: '(beta) preload an app on a disk image (or Edison zip archive)'
|
||||
help: '''
|
||||
Warning: "resin preload" requires Docker to be correctly installed in
|
||||
your shell environment. For more information (including Windows support)
|
||||
please check the README here: https://github.com/resin-io/resin-cli .
|
||||
|
||||
Use this command to preload an application to a local disk image with a
|
||||
built commit from Resin.io.
|
||||
Use this command to preload an application to a local disk image (or
|
||||
Edison zip archive) with a built commit from Resin.io.
|
||||
This can be used with cloud builds, or images deployed with resin deploy.
|
||||
|
||||
Examples:
|
||||
@ -157,9 +157,28 @@ module.exports =
|
||||
preload = require('resin-preload')
|
||||
errors = require('resin-errors')
|
||||
visuals = require('resin-cli-visuals')
|
||||
nodeCleanup = require('node-cleanup')
|
||||
{ expectedError } = require('../utils/patterns')
|
||||
|
||||
imageInfoSpinner = new visuals.Spinner('Reading image device type and preloaded builds.')
|
||||
progressBars = {}
|
||||
|
||||
progressHandler = (event) ->
|
||||
progressBar = progressBars[event.name]
|
||||
if not progressBar
|
||||
progressBar = progressBars[event.name] = new visuals.Progress(event.name)
|
||||
progressBar.update(percentage: event.percentage)
|
||||
|
||||
spinners = {}
|
||||
|
||||
spinnerHandler = (event) ->
|
||||
spinner = spinners[event.name]
|
||||
if not spinner
|
||||
spinner = spinners[event.name] = new visuals.Spinner(event.name)
|
||||
if event.action == 'start'
|
||||
spinner.start()
|
||||
else
|
||||
console.log()
|
||||
spinner.stop()
|
||||
|
||||
options.image = params.image
|
||||
options.appId = options.app
|
||||
@ -171,79 +190,92 @@ module.exports =
|
||||
options.splashImage = options['splash-image']
|
||||
delete options['splash-image']
|
||||
|
||||
if options['dont-check-device-type'] and not options.appId
|
||||
expectedError('You need to specify an app id if you disable the device type check.')
|
||||
|
||||
# Get a configured dockerode instance
|
||||
dockerUtils.getDocker(options)
|
||||
.then (docker) ->
|
||||
|
||||
# Build the preloader image
|
||||
buildOutputStream = preload.build(docker)
|
||||
preloader = new preload.Preloader(
|
||||
resin,
|
||||
docker,
|
||||
options.appId,
|
||||
options.commit,
|
||||
options.image,
|
||||
options.splashImage,
|
||||
options.proxy,
|
||||
options.dontDetectFlasherTypeImages
|
||||
)
|
||||
|
||||
gotSignal = false
|
||||
|
||||
nodeCleanup (exitCode, signal) ->
|
||||
if signal
|
||||
gotSignal = true
|
||||
nodeCleanup.uninstall() # don't call cleanup handler again
|
||||
preloader.cleanup()
|
||||
.then ->
|
||||
# calling process.exit() won't inform parent process of signal
|
||||
process.kill(process.pid, signal)
|
||||
return false
|
||||
|
||||
if process.env.DEBUG
|
||||
buildOutputStream.pipe(process.stdout)
|
||||
preloader.stderr.pipe(process.stderr)
|
||||
|
||||
streamToPromise(buildOutputStream)
|
||||
preloader.on('progress', progressHandler)
|
||||
preloader.on('spinner', spinnerHandler)
|
||||
|
||||
# Get resin sdk settings so we can pass them to the preloader
|
||||
.then(resin.settings.getAll)
|
||||
.then (settings) ->
|
||||
options.proxy = settings.proxy
|
||||
options.apiHost = settings.apiUrl
|
||||
return new Promise (resolve, reject) ->
|
||||
preloader.on('error', reject)
|
||||
|
||||
# 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['dont-check-device-type'] and not options.appId
|
||||
expectedError('You need to specify an app id if you disable the device type check.')
|
||||
if options.appId
|
||||
return preload.getApplication(resin, options.appId)
|
||||
.catch(errors.ResinApplicationNotFound, expectedError)
|
||||
selectApplication(slug)
|
||||
.then (application) ->
|
||||
options.application = application
|
||||
|
||||
# Check that the app device type and the image device type match
|
||||
if slug != application.device_type
|
||||
expectedError(
|
||||
"Image device type (#{application.device_type}) and application device type (#{slug}) do not match"
|
||||
)
|
||||
|
||||
# Use the commit given as --commit or show an interactive commit selection menu
|
||||
Promise.try ->
|
||||
if options.commit
|
||||
if not _.find(application.build, commit_hash: options.commit)
|
||||
expectedError('There is no build matching this commit')
|
||||
return options.commit
|
||||
selectApplicationCommit(application.build)
|
||||
.then (commit) ->
|
||||
|
||||
# No commit specified => use the latest commit
|
||||
if commit == LATEST
|
||||
options.commit = application.commit
|
||||
else
|
||||
options.commit = commit
|
||||
|
||||
# Propose to disable automatic app updates if the commit is not the latest
|
||||
offerToDisableAutomaticUpdates(application, commit)
|
||||
preloader.build()
|
||||
.then ->
|
||||
preloader.prepare()
|
||||
.then ->
|
||||
preloader.getDeviceTypeAndPreloadedBuilds()
|
||||
.then (info) ->
|
||||
Promise.try ->
|
||||
if options.appId
|
||||
return preloader.fetchApplication()
|
||||
.catch(errors.ResinApplicationNotFound, expectedError)
|
||||
selectApplication(info.device_type)
|
||||
.then (application) ->
|
||||
preloader.setApplication(application)
|
||||
# Check that the app device type and the image device type match
|
||||
if info.device_type != application.device_type
|
||||
expectedError(
|
||||
"Image device type (#{application.device_type}) and application device type (#{slug}) do not match"
|
||||
)
|
||||
|
||||
builds = builds.map (build) ->
|
||||
build.slice(-preload.BUILD_HASH_LENGTH)
|
||||
if options.commit in builds
|
||||
console.log('This build is already preloaded in this image.')
|
||||
process.exit(0)
|
||||
# All options are ready: preload the image.
|
||||
preload.run(resin, docker, options)
|
||||
.catch(preload.errors.ResinError, expectedError)
|
||||
.then (info) ->
|
||||
info.stdout.pipe(process.stdout)
|
||||
info.stderr.pipe(process.stderr)
|
||||
info.statusCodePromise
|
||||
.then (statusCode) ->
|
||||
if statusCode != 0
|
||||
process.exit(statusCode)
|
||||
.then(done)
|
||||
# Use the commit given as --commit or show an interactive commit selection menu
|
||||
Promise.try ->
|
||||
if options.commit
|
||||
if not _.find(application.build, commit_hash: options.commit)
|
||||
expectedError('There is no build matching this commit')
|
||||
return options.commit
|
||||
selectApplicationCommit(application.build)
|
||||
.then (commit) ->
|
||||
|
||||
# No commit specified => use the latest commit
|
||||
if commit == LATEST
|
||||
preloader.commit = application.commit
|
||||
else
|
||||
preloader.commit = commit
|
||||
|
||||
# Propose to disable automatic app updates if the commit is not the latest
|
||||
offerToDisableAutomaticUpdates(application, commit)
|
||||
.then ->
|
||||
builds = info.preloaded_builds.map (build) ->
|
||||
build.slice(-preload.BUILD_HASH_LENGTH)
|
||||
if preloader.commit in builds
|
||||
throw new preload.errors.ResinError('This build is already preloaded in this image.')
|
||||
# All options are ready: preload the image.
|
||||
preloader.preload()
|
||||
.catch(preload.errors.ResinError, expectedError)
|
||||
.then(resolve)
|
||||
.catch(reject)
|
||||
.then(done)
|
||||
.finally ->
|
||||
if not gotSignal
|
||||
preloader.cleanup()
|
||||
|
@ -66,6 +66,7 @@
|
||||
"mixpanel": "^0.4.0",
|
||||
"moment": "^2.12.0",
|
||||
"mz": "^2.6.0",
|
||||
"node-cleanup": "^2.1.2",
|
||||
"nplugm": "^3.0.0",
|
||||
"president": "^2.0.1",
|
||||
"prettyjson": "^1.1.3",
|
||||
@ -85,7 +86,7 @@
|
||||
"resin-doodles": "0.0.1",
|
||||
"resin-image-fs": "^2.3.0",
|
||||
"resin-image-manager": "^4.1.1",
|
||||
"resin-preload": "^3.1.4",
|
||||
"resin-preload": "^4.0.2",
|
||||
"resin-sdk-preconfigured": "^6.9.0",
|
||||
"resin-settings-client": "^3.6.1",
|
||||
"resin-stream-logger": "^0.0.4",
|
||||
@ -103,4 +104,4 @@
|
||||
"optionalDependencies": {
|
||||
"removedrive": "^1.0.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user