mirror of
https://github.com/balena-io/balena-cli.git
synced 2025-02-20 17:33:18 +00:00
Merge pull request #64 from resin-io/feature/config-inject
Implement config injection
This commit is contained in:
commit
47e6371e2e
@ -1,5 +1,7 @@
|
||||
(function() {
|
||||
var _, async, capitano, commandOptions, osAction, path, resin, tmp, vcs, visuals;
|
||||
var _, async, capitano, commandOptions, fse, image, inject, manager, path, pine, registerDevice, resin, tmp, vcs, visuals;
|
||||
|
||||
fse = require('fs-extra');
|
||||
|
||||
capitano = require('capitano');
|
||||
|
||||
@ -15,14 +17,22 @@
|
||||
|
||||
vcs = require('resin-vcs');
|
||||
|
||||
manager = require('resin-image-manager');
|
||||
|
||||
image = require('resin-image');
|
||||
|
||||
inject = require('resin-config-inject');
|
||||
|
||||
registerDevice = require('resin-register-device');
|
||||
|
||||
pine = require('resin-pine');
|
||||
|
||||
tmp = require('tmp');
|
||||
|
||||
tmp.setGracefulCleanup();
|
||||
|
||||
commandOptions = require('./command-options');
|
||||
|
||||
osAction = require('./os');
|
||||
|
||||
exports.list = {
|
||||
signature: 'devices',
|
||||
description: 'list all devices',
|
||||
@ -159,10 +169,17 @@
|
||||
exports.init = {
|
||||
signature: 'device init [device]',
|
||||
description: 'initialise a device with resin os',
|
||||
help: 'Use this command to download the OS image of a certain application and write it to an SD Card.\n\nNote that this command requires admin privileges.\n\nIf `device` is omitted, you will be prompted to select a device interactively.\n\nNotice this command asks for confirmation interactively.\nYou can avoid this by passing the `--yes` boolean option.\n\nYou can quiet the progress bar by passing the `--quiet` boolean option.\n\nYou may have to unmount the device before attempting this operation.\n\nYou need to configure the network type and other settings:\n\nEthernet:\n You can setup the device OS to use ethernet by setting the `--network` option to "ethernet".\n\nWifi:\n You can setup the device OS to use wifi by setting the `--network` option to "wifi".\n If you set "network" to "wifi", you will need to specify the `--ssid` and `--key` option as well.\n\nYou can omit network related options to be asked about them interactively.\n\nExamples:\n\n $ resin device init\n $ resin device init --application MyApp\n $ resin device init --application MyApp --network ethernet\n $ resin device init /dev/disk2 --application MyApp --network wifi --ssid MyNetwork --key secret',
|
||||
help: 'Use this command to download the OS image of a certain application and write it to an SD Card.\n\nNote that this command requires admin privileges.\n\nIf `device` is omitted, you will be prompted to select a device interactively.\n\nNotice this command asks for confirmation interactively.\nYou can avoid this by passing the `--yes` boolean option.\n\nYou can quiet the progress bar and other logging information by passing the `--quiet` boolean option.\n\nYou need to configure the network type and other settings:\n\nEthernet:\n You can setup the device OS to use ethernet by setting the `--network` option to "ethernet".\n\nWifi:\n You can setup the device OS to use wifi by setting the `--network` option to "wifi".\n If you set "network" to "wifi", you will need to specify the `--ssid` and `--key` option as well.\n\nYou can omit network related options to be asked about them interactively.\n\nExamples:\n\n $ resin device init\n $ resin device init --application MyApp\n $ resin device init --application MyApp --network ethernet\n $ resin device init /dev/disk2 --application MyApp --network wifi --ssid MyNetwork --key secret',
|
||||
options: [commandOptions.optionalApplication, commandOptions.network, commandOptions.wifiSsid, commandOptions.wifiKey],
|
||||
permission: 'user',
|
||||
root: true,
|
||||
action: function(params, options, done) {
|
||||
var networkOptions;
|
||||
networkOptions = {
|
||||
network: options.network,
|
||||
wifiSsid: options.ssid,
|
||||
wifiKey: options.key
|
||||
};
|
||||
return async.waterfall([
|
||||
function(callback) {
|
||||
if (options.application != null) {
|
||||
@ -170,7 +187,7 @@
|
||||
}
|
||||
return vcs.getApplicationName(process.cwd(), callback);
|
||||
}, function(applicationName, callback) {
|
||||
params.name = applicationName;
|
||||
options.application = applicationName;
|
||||
if (params.device != null) {
|
||||
return callback(null, params.device);
|
||||
}
|
||||
@ -184,27 +201,81 @@
|
||||
if (!confirmed) {
|
||||
return done();
|
||||
}
|
||||
options.yes = confirmed;
|
||||
return tmp.file({
|
||||
prefix: 'resin-image-',
|
||||
postfix: '.img'
|
||||
}, callback);
|
||||
}, function(tmpPath, tmpFd, cleanupCallback, callback) {
|
||||
options.output = tmpPath;
|
||||
return osAction.download.action(params, options, function(error, outputFile) {
|
||||
if (networkOptions.network != null) {
|
||||
return callback();
|
||||
}
|
||||
return visuals.patterns.selectNetworkParameters(function(error, parameters) {
|
||||
if (error != null) {
|
||||
return callback(error);
|
||||
}
|
||||
return callback(null, outputFile, cleanupCallback);
|
||||
});
|
||||
}, function(outputFile, cleanupCallback, callback) {
|
||||
return capitano.run("os install " + outputFile + " " + params.device, function(error) {
|
||||
if (error != null) {
|
||||
return callback(error);
|
||||
}
|
||||
cleanupCallback();
|
||||
_.extend(networkOptions, parameters);
|
||||
return callback();
|
||||
});
|
||||
}, function(callback) {
|
||||
console.info("Checking application: " + options.application);
|
||||
return resin.models.application.get(options.application, callback);
|
||||
}, function(application, callback) {
|
||||
return async.parallel({
|
||||
manifest: function(callback) {
|
||||
console.info('Getting device manifest for the application');
|
||||
return resin.models.device.getManifestBySlug(application.device_type, callback);
|
||||
},
|
||||
config: function(callback) {
|
||||
console.info('Fetching application configuration');
|
||||
return resin.models.application.getConfiguration(options.application, networkOptions, callback);
|
||||
}
|
||||
}, callback);
|
||||
}, function(results, callback) {
|
||||
console.info('Associating the device');
|
||||
return registerDevice.register(pine, results.config, function(error, device) {
|
||||
if (error != null) {
|
||||
return callback(error);
|
||||
}
|
||||
results.config.deviceId = device.id;
|
||||
results.config.uuid = device.uuid;
|
||||
params.uuid = results.config.uuid;
|
||||
return callback(null, results);
|
||||
});
|
||||
}, function(results, callback) {
|
||||
var bar, spinner;
|
||||
console.info('Configuring device operating system image');
|
||||
if (process.env.DEBUG) {
|
||||
console.log(results.config);
|
||||
}
|
||||
bar = new visuals.widgets.Progress('Downloading Device OS');
|
||||
spinner = new visuals.widgets.Spinner('Downloading Device OS (size unknown)');
|
||||
return manager.configure(results.manifest, results.config, function(error, imagePath, removeCallback) {
|
||||
spinner.stop();
|
||||
return callback(error, imagePath, removeCallback);
|
||||
}, function(state) {
|
||||
if (state != null) {
|
||||
return bar.update(state);
|
||||
} else {
|
||||
return spinner.start();
|
||||
}
|
||||
});
|
||||
}, function(configuredImagePath, removeCallback, callback) {
|
||||
var bar;
|
||||
console.info('Attempting to write operating system image to drive');
|
||||
bar = new visuals.widgets.Progress('Writing Device OS');
|
||||
return image.write({
|
||||
device: params.device,
|
||||
image: configuredImagePath,
|
||||
progress: _.bind(bar.update, bar)
|
||||
}, function(error) {
|
||||
if (error != null) {
|
||||
return callback(error);
|
||||
}
|
||||
return callback(null, configuredImagePath, removeCallback);
|
||||
});
|
||||
}, function(temporalImagePath, removeCallback, callback) {
|
||||
console.info('Image written successfully');
|
||||
return removeCallback(callback);
|
||||
}, function(callback) {
|
||||
return resin.models.device.getByUUID(params.uuid, callback);
|
||||
}, function(device, callback) {
|
||||
console.info("Device created: " + device.name);
|
||||
return callback(null, device.name);
|
||||
}
|
||||
], done);
|
||||
}
|
||||
|
@ -10,7 +10,6 @@
|
||||
logs: require('./logs'),
|
||||
notes: require('./notes'),
|
||||
preferences: require('./preferences'),
|
||||
os: require('./os'),
|
||||
help: require('./help'),
|
||||
examples: require('./examples'),
|
||||
plugin: require('./plugin'),
|
||||
|
@ -1,155 +0,0 @@
|
||||
(function() {
|
||||
var _, async, capitano, commandOptions, elevate, image, mkdirp, os, packageJSON, path, resin, selfupdate, visuals;
|
||||
|
||||
capitano = require('capitano');
|
||||
|
||||
_ = require('lodash-contrib');
|
||||
|
||||
os = require('os');
|
||||
|
||||
async = require('async');
|
||||
|
||||
path = require('path');
|
||||
|
||||
mkdirp = require('mkdirp');
|
||||
|
||||
resin = require('resin-sdk');
|
||||
|
||||
image = require('resin-image');
|
||||
|
||||
visuals = require('resin-cli-visuals');
|
||||
|
||||
selfupdate = require('selfupdate');
|
||||
|
||||
commandOptions = require('./command-options');
|
||||
|
||||
packageJSON = require('../../package.json');
|
||||
|
||||
elevate = require('../elevate');
|
||||
|
||||
exports.download = {
|
||||
signature: 'os download <name>',
|
||||
description: 'download device OS',
|
||||
help: 'Use this command to download the device OS configured to a specific network.\n\nEthernet:\n You can setup the device OS to use ethernet by setting the `--network` option to "ethernet".\n\nWifi:\n You can setup the device OS to use wifi by setting the `--network` option to "wifi".\n If you set "network" to "wifi", you will need to specify the `--ssid` and `--key` option as well.\n\nAlternatively, you can omit all kind of network configuration options to configure interactively.\n\nYou have to specify an output location with the `--output` option.\n\nExamples:\n\n $ resin os download MyApp --output ~/MyResinOS.zip\n $ resin os download MyApp --network ethernet --output ~/MyResinOS.zip\n $ resin os download MyApp --network wifi --ssid MyNetwork --key secreykey123 --output ~/MyResinOS.zip\n $ resin os download MyApp --network ethernet --output ~/MyResinOS.zip',
|
||||
options: [
|
||||
commandOptions.network, commandOptions.wifiSsid, commandOptions.wifiKey, {
|
||||
signature: 'output',
|
||||
parameter: 'output',
|
||||
description: 'output file',
|
||||
alias: 'o',
|
||||
required: 'You need to specify an output file'
|
||||
}
|
||||
],
|
||||
permission: 'user',
|
||||
action: function(params, options, done) {
|
||||
return resin.models.application.get(params.name, function(error, application) {
|
||||
var osParams;
|
||||
if (error != null) {
|
||||
return done(error);
|
||||
}
|
||||
osParams = {
|
||||
network: options.network,
|
||||
wifiSsid: options.ssid,
|
||||
wifiKey: options.key,
|
||||
appId: application.id
|
||||
};
|
||||
return async.waterfall([
|
||||
function(callback) {
|
||||
if (osParams.network != null) {
|
||||
return callback();
|
||||
}
|
||||
return visuals.patterns.selectNetworkParameters(function(error, parameters) {
|
||||
if (error != null) {
|
||||
return callback(error);
|
||||
}
|
||||
_.extend(osParams, parameters);
|
||||
return callback();
|
||||
});
|
||||
}, function(callback) {
|
||||
return mkdirp(path.dirname(options.output), _.unary(callback));
|
||||
}, function(callback) {
|
||||
var bar, spinner;
|
||||
console.info("Destination file: " + options.output + "\n");
|
||||
bar = new visuals.widgets.Progress('Downloading Device OS');
|
||||
spinner = new visuals.widgets.Spinner('Downloading Device OS (size unknown)');
|
||||
return resin.models.os.download(osParams, options.output, function(error) {
|
||||
spinner.stop();
|
||||
return callback(error);
|
||||
}, function(state) {
|
||||
if (state != null) {
|
||||
return bar.update(state);
|
||||
} else {
|
||||
return spinner.start();
|
||||
}
|
||||
});
|
||||
}
|
||||
], function(error) {
|
||||
if (error != null) {
|
||||
return done(error);
|
||||
}
|
||||
console.info("\nFinished downloading " + options.output);
|
||||
return done(null, options.output);
|
||||
});
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
exports.install = {
|
||||
signature: 'os install <image> [device]',
|
||||
description: 'write an operating system image to a device',
|
||||
help: 'Use this command to write an operating system image to a device.\n\nNote that this command requires admin privileges.\n\nIf `device` is omitted, you will be prompted to select a device interactively.\n\nNotice this command asks for confirmation interactively.\nYou can avoid this by passing the `--yes` boolean option.\n\nYou can quiet the progress bar by passing the `--quiet` boolean option.\n\nExamples:\n\n $ resin os install rpi.iso /dev/disk2',
|
||||
options: [commandOptions.yes],
|
||||
permission: 'user',
|
||||
action: function(params, options, done) {
|
||||
return async.waterfall([
|
||||
function(callback) {
|
||||
return selfupdate.isUpdated(packageJSON, callback);
|
||||
}, function(isUpdated, callback) {
|
||||
if (isUpdated) {
|
||||
return callback();
|
||||
}
|
||||
console.info('Resin CLI is outdated.\n\nIn order to avoid device compatibility issues, this command\nrequires that you have the Resin CLI updated.\n\nUpdating now...');
|
||||
return capitano.run('update', _.unary(callback));
|
||||
}, function(callback) {
|
||||
if (params.device != null) {
|
||||
return callback(null, params.device);
|
||||
}
|
||||
return visuals.patterns.selectDrive(function(error, device) {
|
||||
if (error != null) {
|
||||
return callback(error);
|
||||
}
|
||||
if (device == null) {
|
||||
return callback(new Error('No removable devices available'));
|
||||
}
|
||||
return callback(null, device);
|
||||
});
|
||||
}, function(device, callback) {
|
||||
var message;
|
||||
params.device = device;
|
||||
message = "This will completely erase " + params.device + ". Are you sure you want to continue?";
|
||||
return visuals.patterns.confirm(options.yes, message, callback);
|
||||
}, function(confirmed, callback) {
|
||||
var bar;
|
||||
if (!confirmed) {
|
||||
return done();
|
||||
}
|
||||
bar = new visuals.widgets.Progress('Writing Device OS');
|
||||
params.progress = _.bind(bar.update, bar);
|
||||
return image.write(params, callback);
|
||||
}
|
||||
], function(error) {
|
||||
var resinWritePath;
|
||||
if (error == null) {
|
||||
return done();
|
||||
}
|
||||
if (elevate.shouldElevate(error) && !options.fromScript) {
|
||||
resinWritePath = "\"" + (path.join(__dirname, '..', '..', 'bin', 'resin-write')) + "\"";
|
||||
return elevate.run("\"" + process.argv[0] + "\" " + resinWritePath + " \"" + params.image + "\" \"" + params.device + "\"");
|
||||
} else {
|
||||
return done(error);
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
}).call(this);
|
@ -128,10 +128,6 @@
|
||||
|
||||
capitano.command(actions.logs);
|
||||
|
||||
capitano.command(actions.os.download);
|
||||
|
||||
capitano.command(actions.os.install);
|
||||
|
||||
capitano.command(actions.examples.list);
|
||||
|
||||
capitano.command(actions.examples.clone);
|
||||
|
@ -1,3 +1,4 @@
|
||||
fse = require('fs-extra')
|
||||
capitano = require('capitano')
|
||||
_ = require('lodash-contrib')
|
||||
path = require('path')
|
||||
@ -5,13 +6,17 @@ async = require('async')
|
||||
resin = require('resin-sdk')
|
||||
visuals = require('resin-cli-visuals')
|
||||
vcs = require('resin-vcs')
|
||||
manager = require('resin-image-manager')
|
||||
image = require('resin-image')
|
||||
inject = require('resin-config-inject')
|
||||
registerDevice = require('resin-register-device')
|
||||
pine = require('resin-pine')
|
||||
tmp = require('tmp')
|
||||
|
||||
# Cleanup the temporary files even when an uncaught exception occurs
|
||||
tmp.setGracefulCleanup()
|
||||
|
||||
commandOptions = require('./command-options')
|
||||
osAction = require('./os')
|
||||
|
||||
exports.list =
|
||||
signature: 'devices'
|
||||
@ -217,9 +222,7 @@ exports.init =
|
||||
Notice this command asks for confirmation interactively.
|
||||
You can avoid this by passing the `--yes` boolean option.
|
||||
|
||||
You can quiet the progress bar by passing the `--quiet` boolean option.
|
||||
|
||||
You may have to unmount the device before attempting this operation.
|
||||
You can quiet the progress bar and other logging information by passing the `--quiet` boolean option.
|
||||
|
||||
You need to configure the network type and other settings:
|
||||
|
||||
@ -246,8 +249,14 @@ exports.init =
|
||||
commandOptions.wifiKey
|
||||
]
|
||||
permission: 'user'
|
||||
root: true
|
||||
action: (params, options, done) ->
|
||||
|
||||
networkOptions =
|
||||
network: options.network
|
||||
wifiSsid: options.ssid
|
||||
wifiKey: options.key
|
||||
|
||||
async.waterfall([
|
||||
|
||||
(callback) ->
|
||||
@ -255,7 +264,7 @@ exports.init =
|
||||
vcs.getApplicationName(process.cwd(), callback)
|
||||
|
||||
(applicationName, callback) ->
|
||||
params.name = applicationName
|
||||
options.application = applicationName
|
||||
return callback(null, params.device) if params.device?
|
||||
visuals.patterns.selectDrive(callback)
|
||||
|
||||
@ -266,27 +275,82 @@ exports.init =
|
||||
|
||||
(confirmed, callback) ->
|
||||
return done() if not confirmed
|
||||
options.yes = confirmed
|
||||
|
||||
tmp.file
|
||||
prefix: 'resin-image-'
|
||||
postfix: '.img'
|
||||
, callback
|
||||
|
||||
(tmpPath, tmpFd, cleanupCallback, callback) ->
|
||||
options.output = tmpPath
|
||||
|
||||
# TODO: Figure out how to make use of capitano.run()
|
||||
# here given the complexity of converting network
|
||||
# params object to string options
|
||||
osAction.download.action params, options, (error, outputFile) ->
|
||||
return callback() if networkOptions.network?
|
||||
visuals.patterns.selectNetworkParameters (error, parameters) ->
|
||||
return callback(error) if error?
|
||||
return callback(null, outputFile, cleanupCallback)
|
||||
|
||||
(outputFile, cleanupCallback, callback) ->
|
||||
capitano.run "os install #{outputFile} #{params.device}", (error) ->
|
||||
return callback(error) if error?
|
||||
cleanupCallback()
|
||||
_.extend(networkOptions, parameters)
|
||||
return callback()
|
||||
|
||||
(callback) ->
|
||||
console.info("Checking application: #{options.application}")
|
||||
resin.models.application.get(options.application, callback)
|
||||
|
||||
(application, callback) ->
|
||||
async.parallel
|
||||
|
||||
manifest: (callback) ->
|
||||
console.info('Getting device manifest for the application')
|
||||
resin.models.device.getManifestBySlug(application.device_type, callback)
|
||||
|
||||
config: (callback) ->
|
||||
console.info('Fetching application configuration')
|
||||
resin.models.application.getConfiguration(options.application, networkOptions, callback)
|
||||
|
||||
, callback
|
||||
|
||||
(results, callback) ->
|
||||
console.info('Associating the device')
|
||||
|
||||
registerDevice.register pine, results.config, (error, device) ->
|
||||
return callback(error) if error?
|
||||
|
||||
# Associate a device
|
||||
results.config.deviceId = device.id
|
||||
results.config.uuid = device.uuid
|
||||
|
||||
params.uuid = results.config.uuid
|
||||
|
||||
return callback(null, results)
|
||||
|
||||
(results, callback) ->
|
||||
console.info('Configuring device operating system image')
|
||||
|
||||
if process.env.DEBUG
|
||||
console.log(results.config)
|
||||
|
||||
bar = new visuals.widgets.Progress('Downloading Device OS')
|
||||
spinner = new visuals.widgets.Spinner('Downloading Device OS (size unknown)')
|
||||
|
||||
manager.configure results.manifest, results.config, (error, imagePath, removeCallback) ->
|
||||
spinner.stop()
|
||||
return callback(error, imagePath, removeCallback)
|
||||
, (state) ->
|
||||
if state?
|
||||
bar.update(state)
|
||||
else
|
||||
spinner.start()
|
||||
|
||||
(configuredImagePath, removeCallback, callback) ->
|
||||
console.info('Attempting to write operating system image to drive')
|
||||
|
||||
bar = new visuals.widgets.Progress('Writing Device OS')
|
||||
image.write
|
||||
device: params.device
|
||||
image: configuredImagePath
|
||||
progress: _.bind(bar.update, bar)
|
||||
, (error) ->
|
||||
return callback(error) if error?
|
||||
return callback(null, configuredImagePath, removeCallback)
|
||||
|
||||
(temporalImagePath, removeCallback, callback) ->
|
||||
console.info('Image written successfully')
|
||||
removeCallback(callback)
|
||||
|
||||
(callback) ->
|
||||
resin.models.device.getByUUID(params.uuid, callback)
|
||||
|
||||
(device, callback) ->
|
||||
console.info("Device created: #{device.name}")
|
||||
return callback(null, device.name)
|
||||
|
||||
], done)
|
||||
|
@ -9,7 +9,6 @@ module.exports =
|
||||
logs: require('./logs')
|
||||
notes: require('./notes')
|
||||
preferences: require('./preferences')
|
||||
os: require('./os')
|
||||
help: require('./help')
|
||||
examples: require('./examples')
|
||||
plugin: require('./plugin')
|
||||
|
@ -1,171 +0,0 @@
|
||||
capitano = require('capitano')
|
||||
_ = require('lodash-contrib')
|
||||
os = require('os')
|
||||
async = require('async')
|
||||
path = require('path')
|
||||
mkdirp = require('mkdirp')
|
||||
resin = require('resin-sdk')
|
||||
image = require('resin-image')
|
||||
visuals = require('resin-cli-visuals')
|
||||
selfupdate = require('selfupdate')
|
||||
commandOptions = require('./command-options')
|
||||
packageJSON = require('../../package.json')
|
||||
elevate = require('../elevate')
|
||||
|
||||
exports.download =
|
||||
signature: 'os download <name>'
|
||||
description: 'download device OS'
|
||||
help: '''
|
||||
Use this command to download the device OS configured to a specific network.
|
||||
|
||||
Ethernet:
|
||||
You can setup the device OS to use ethernet by setting the `--network` option to "ethernet".
|
||||
|
||||
Wifi:
|
||||
You can setup the device OS to use wifi by setting the `--network` option to "wifi".
|
||||
If you set "network" to "wifi", you will need to specify the `--ssid` and `--key` option as well.
|
||||
|
||||
Alternatively, you can omit all kind of network configuration options to configure interactively.
|
||||
|
||||
You have to specify an output location with the `--output` option.
|
||||
|
||||
Examples:
|
||||
|
||||
$ resin os download MyApp --output ~/MyResinOS.zip
|
||||
$ resin os download MyApp --network ethernet --output ~/MyResinOS.zip
|
||||
$ resin os download MyApp --network wifi --ssid MyNetwork --key secreykey123 --output ~/MyResinOS.zip
|
||||
$ resin os download MyApp --network ethernet --output ~/MyResinOS.zip
|
||||
'''
|
||||
options: [
|
||||
commandOptions.network
|
||||
commandOptions.wifiSsid
|
||||
commandOptions.wifiKey
|
||||
|
||||
{
|
||||
signature: 'output'
|
||||
parameter: 'output'
|
||||
description: 'output file'
|
||||
alias: 'o'
|
||||
required: 'You need to specify an output file'
|
||||
}
|
||||
]
|
||||
permission: 'user'
|
||||
action: (params, options, done) ->
|
||||
resin.models.application.get params.name, (error, application) ->
|
||||
return done(error) if error?
|
||||
|
||||
osParams =
|
||||
network: options.network
|
||||
wifiSsid: options.ssid
|
||||
wifiKey: options.key
|
||||
appId: application.id
|
||||
|
||||
async.waterfall [
|
||||
|
||||
(callback) ->
|
||||
return callback() if osParams.network?
|
||||
visuals.patterns.selectNetworkParameters (error, parameters) ->
|
||||
return callback(error) if error?
|
||||
_.extend(osParams, parameters)
|
||||
return callback()
|
||||
|
||||
(callback) ->
|
||||
|
||||
# We need to ensure this directory exists
|
||||
mkdirp(path.dirname(options.output), _.unary(callback))
|
||||
|
||||
(callback) ->
|
||||
console.info("Destination file: #{options.output}\n")
|
||||
|
||||
bar = new visuals.widgets.Progress('Downloading Device OS')
|
||||
spinner = new visuals.widgets.Spinner('Downloading Device OS (size unknown)')
|
||||
|
||||
resin.models.os.download osParams, options.output, (error) ->
|
||||
spinner.stop()
|
||||
return callback(error)
|
||||
, (state) ->
|
||||
if state?
|
||||
bar.update(state)
|
||||
else
|
||||
spinner.start()
|
||||
|
||||
], (error) ->
|
||||
return done(error) if error?
|
||||
console.info("\nFinished downloading #{options.output}")
|
||||
return done(null, options.output)
|
||||
|
||||
exports.install =
|
||||
signature: 'os install <image> [device]'
|
||||
description: 'write an operating system image to a device'
|
||||
help: '''
|
||||
Use this command to write an operating system image to a device.
|
||||
|
||||
Note that this command requires admin privileges.
|
||||
|
||||
If `device` is omitted, you will be prompted to select a device interactively.
|
||||
|
||||
Notice this command asks for confirmation interactively.
|
||||
You can avoid this by passing the `--yes` boolean option.
|
||||
|
||||
You can quiet the progress bar by passing the `--quiet` boolean option.
|
||||
|
||||
Examples:
|
||||
|
||||
$ resin os install rpi.iso /dev/disk2
|
||||
'''
|
||||
options: [ commandOptions.yes ]
|
||||
permission: 'user'
|
||||
action: (params, options, done) ->
|
||||
|
||||
async.waterfall [
|
||||
|
||||
(callback) ->
|
||||
selfupdate.isUpdated(packageJSON, callback)
|
||||
|
||||
(isUpdated, callback) ->
|
||||
return callback() if isUpdated
|
||||
|
||||
console.info '''
|
||||
Resin CLI is outdated.
|
||||
|
||||
In order to avoid device compatibility issues, this command
|
||||
requires that you have the Resin CLI updated.
|
||||
|
||||
Updating now...
|
||||
'''
|
||||
|
||||
capitano.run('update', _.unary(callback))
|
||||
|
||||
(callback) ->
|
||||
return callback(null, params.device) if params.device?
|
||||
|
||||
# TODO: See if we can reuse the drives action somehow here
|
||||
visuals.patterns.selectDrive (error, device) ->
|
||||
return callback(error) if error?
|
||||
|
||||
if not device?
|
||||
return callback(new Error('No removable devices available'))
|
||||
|
||||
return callback(null, device)
|
||||
|
||||
(device, callback) ->
|
||||
params.device = device
|
||||
message = "This will completely erase #{params.device}. Are you sure you want to continue?"
|
||||
visuals.patterns.confirm(options.yes, message, callback)
|
||||
|
||||
(confirmed, callback) ->
|
||||
return done() if not confirmed
|
||||
bar = new visuals.widgets.Progress('Writing Device OS')
|
||||
params.progress = _.bind(bar.update, bar)
|
||||
image.write(params, callback)
|
||||
|
||||
], (error) ->
|
||||
return done() if not error?
|
||||
|
||||
if elevate.shouldElevate(error) and not options.fromScript
|
||||
|
||||
# Need to escape every path to avoid errors
|
||||
resinWritePath = "\"#{path.join(__dirname, '..', '..', 'bin', 'resin-write')}\""
|
||||
elevate.run("\"#{process.argv[0]}\" #{resinWritePath} \"#{params.image}\" \"#{params.device}\"")
|
||||
else
|
||||
return done(error)
|
@ -100,10 +100,6 @@ capitano.command(actions.env.remove)
|
||||
# ---------- Logs Module ----------
|
||||
capitano.command(actions.logs)
|
||||
|
||||
# ---------- OS Module ----------
|
||||
capitano.command(actions.os.download)
|
||||
capitano.command(actions.os.install)
|
||||
|
||||
# ---------- Examples Module ----------
|
||||
capitano.command(actions.examples.list)
|
||||
capitano.command(actions.examples.clone)
|
||||
|
@ -52,15 +52,20 @@
|
||||
"coffee-script": "~1.8.0",
|
||||
"conf.js": "^0.1.1",
|
||||
"drivelist": "^1.2.2",
|
||||
"fs-extra": "^0.18.3",
|
||||
"lodash": "~2.4.1",
|
||||
"lodash-contrib": "~241.4.14",
|
||||
"mkdirp": "~0.5.0",
|
||||
"nplugm": "^2.2.0",
|
||||
"npm": "^2.6.1",
|
||||
"open": "0.0.5",
|
||||
"resin-cli-visuals": "^0.1.0",
|
||||
"resin-cli-visuals": "^0.1.1",
|
||||
"resin-config-inject": "^2.0.0",
|
||||
"resin-image": "^1.1.3",
|
||||
"resin-sdk": "^1.7.3",
|
||||
"resin-image-manager": "^1.1.0",
|
||||
"resin-pine": "^1.1.1",
|
||||
"resin-register-device": "^1.0.1",
|
||||
"resin-sdk": "^1.7.4",
|
||||
"resin-settings-client": "^1.1.0",
|
||||
"resin-vcs": "^1.2.0",
|
||||
"selfupdate": "^1.1.0",
|
||||
|
Loading…
x
Reference in New Issue
Block a user