mirror of
https://github.com/balena-io/balena-cli.git
synced 2025-01-18 10:46:34 +00:00
Implement Quickstart command
This commit is contained in:
parent
d24b871964
commit
dc030f4cd1
@ -41,12 +41,10 @@
|
||||
if (options.type != null) {
|
||||
return callback(null, options.type);
|
||||
}
|
||||
return resin.models.device.getSupportedDeviceTypes().then(function(supportedDeviceTypes) {
|
||||
return form.ask({
|
||||
message: 'Device Type',
|
||||
type: 'list',
|
||||
choices: supportedDeviceTypes
|
||||
});
|
||||
choices: ['Raspberry Pi', 'Raspberry Pi 2', 'BeagleBone Black']
|
||||
}).nodeify(callback);
|
||||
}, function(type, callback) {
|
||||
options.type = type;
|
||||
|
@ -1,5 +1,5 @@
|
||||
(function() {
|
||||
var _, async, capitano, commandOptions, deviceConfig, drivelist, form, fse, image, inject, manager, path, pine, registerDevice, resin, tmp, vcs, visuals;
|
||||
var _, async, capitano, commandOptions, deviceConfig, drivelist, form, fse, htmlToText, image, inject, manager, os, path, pine, registerDevice, resin, tmp, vcs, visuals;
|
||||
|
||||
fse = require('fs-extra');
|
||||
|
||||
@ -35,6 +35,10 @@
|
||||
|
||||
drivelist = require('drivelist');
|
||||
|
||||
htmlToText = require('html-to-text');
|
||||
|
||||
os = require('os');
|
||||
|
||||
tmp.setGracefulCleanup();
|
||||
|
||||
commandOptions = require('./command-options');
|
||||
@ -291,6 +295,7 @@
|
||||
}
|
||||
}, callback);
|
||||
}, function(results, callback) {
|
||||
params.manifest = results.manifest;
|
||||
console.info('Associating the device');
|
||||
return registerDevice.register(pine, results.config, function(error, device) {
|
||||
if (error != null) {
|
||||
@ -310,7 +315,7 @@
|
||||
}
|
||||
bar = new visuals.Progress('Downloading Device OS');
|
||||
spinner = new visuals.Spinner('Downloading Device OS (size unknown)');
|
||||
return manager.configure(results.manifest, results.config, function(error, imagePath, removeCallback) {
|
||||
return manager.configure(params.manifest, results.config, function(error, imagePath, removeCallback) {
|
||||
spinner.stop();
|
||||
return callback(error, imagePath, removeCallback);
|
||||
}, function(state) {
|
||||
@ -322,6 +327,7 @@
|
||||
});
|
||||
}, function(configuredImagePath, removeCallback, callback) {
|
||||
var bar;
|
||||
console.info('The base image was cached to improve initialization time of similar devices');
|
||||
console.info('Attempting to write operating system image to drive');
|
||||
bar = new visuals.Progress('Writing Device OS');
|
||||
return image.write({
|
||||
@ -342,6 +348,28 @@
|
||||
}, function(device, callback) {
|
||||
console.info("Device created: " + device.name);
|
||||
return callback(null, device.name);
|
||||
}, function(deviceName, callback) {
|
||||
var instructions, osSpecificInstructions, platform, platformHash;
|
||||
if (params.manifest.instructions == null) {
|
||||
instructions = '';
|
||||
}
|
||||
if (_.isArray(params.manifest.instructions)) {
|
||||
instructions = htmlToText.fromString(params.manifest.instructions.join('\n'));
|
||||
}
|
||||
platformHash = {
|
||||
darwin: 'osx',
|
||||
linux: 'linux',
|
||||
win32: 'windows'
|
||||
};
|
||||
platform = platformHash[os.platform()];
|
||||
osSpecificInstructions = params.manifest.instructions[platform];
|
||||
if (osSpecificInstructions == null) {
|
||||
instructions = '';
|
||||
} else {
|
||||
instructions = htmlToText.fromString(osSpecificInstructions.join('\n'));
|
||||
}
|
||||
console.log('\n' + instructions);
|
||||
return callback(null, params.uuid);
|
||||
}
|
||||
], done);
|
||||
}
|
||||
|
@ -1,5 +1,6 @@
|
||||
(function() {
|
||||
module.exports = {
|
||||
wizard: require('./wizard'),
|
||||
app: require('./app'),
|
||||
info: require('./info'),
|
||||
auth: require('./auth'),
|
||||
|
110
build/actions/wizard.js
Normal file
110
build/actions/wizard.js
Normal file
@ -0,0 +1,110 @@
|
||||
(function() {
|
||||
var Promise, _, async, capitano, form, mkdirp, path, resin, userHome, visuals;
|
||||
|
||||
_ = require('lodash-contrib');
|
||||
|
||||
Promise = require('bluebird');
|
||||
|
||||
capitano = Promise.promisifyAll(require('capitano'));
|
||||
|
||||
path = require('path');
|
||||
|
||||
mkdirp = require('mkdirp');
|
||||
|
||||
userHome = require('user-home');
|
||||
|
||||
visuals = require('resin-cli-visuals');
|
||||
|
||||
async = require('async');
|
||||
|
||||
resin = require('resin-sdk');
|
||||
|
||||
form = require('resin-cli-form');
|
||||
|
||||
exports.wizard = {
|
||||
signature: 'quickstart [name]',
|
||||
description: 'getting started with resin.io',
|
||||
help: 'Use this command to run a friendly wizard to get started with resin.io.\n\nThe wizard will guide you through:\n\n - Create an application.\n - Initialise an SDCard with the resin.io operating system.\n - Associate an existing project directory with your resin.io application.\n - Push your project to your devices.\n\nExamples:\n\n $ sudo resin quickstart\n $ sudo resin quickstart MyApp',
|
||||
root: true,
|
||||
permission: 'user',
|
||||
action: function(params, options, done) {
|
||||
return async.waterfall([
|
||||
function(callback) {
|
||||
if (params.name != null) {
|
||||
return callback();
|
||||
}
|
||||
return async.waterfall([
|
||||
function(callback) {
|
||||
return resin.models.application.hasAny().nodeify(callback);
|
||||
}, function(hasAnyApplications, callback) {
|
||||
if (!hasAnyApplications) {
|
||||
return callback(null, null);
|
||||
}
|
||||
return async.waterfall([
|
||||
function(callback) {
|
||||
return resin.models.application.getAll().nodeify(callback);
|
||||
}, function(applications, callback) {
|
||||
applications = _.pluck(applications, 'app_name');
|
||||
applications.unshift({
|
||||
name: 'Create a new application',
|
||||
value: null
|
||||
});
|
||||
return form.ask({
|
||||
message: 'Select an application',
|
||||
type: 'list',
|
||||
choices: applications
|
||||
}).nodeify(callback);
|
||||
}
|
||||
], callback);
|
||||
}, function(application, callback) {
|
||||
if (application != null) {
|
||||
return callback(null, application);
|
||||
}
|
||||
return form.ask({
|
||||
message: 'Choose a Name for your new application',
|
||||
type: 'input'
|
||||
}).then(function(applicationName) {
|
||||
return capitano.runAsync("app create " + applicationName)["return"](applicationName);
|
||||
}).nodeify(callback);
|
||||
}, function(applicationName, callback) {
|
||||
params.name = applicationName;
|
||||
return callback();
|
||||
}
|
||||
], callback);
|
||||
}, function(callback) {
|
||||
return capitano.run("device init --application " + params.name, callback);
|
||||
}, function(deviceUuid, callback) {
|
||||
params.uuid = deviceUuid;
|
||||
return resin.models.device.getName(params.uuid).then(function(deviceName) {
|
||||
params.deviceName = deviceName;
|
||||
console.log("Waiting for " + params.deviceName + " to connect to resin...");
|
||||
return capitano.runAsync("device await " + params.uuid)["return"](callback);
|
||||
}).nodeify(callback);
|
||||
}, function(callback) {
|
||||
console.log("The device " + params.deviceName + " successfully connected to resin!");
|
||||
console.log('');
|
||||
return capitano.run("device " + params.uuid, callback);
|
||||
}, function(callback) {
|
||||
console.log('Your device is ready, lets start pushing some code!');
|
||||
return form.ask({
|
||||
message: 'Please choose a directory for your code',
|
||||
type: 'input',
|
||||
"default": path.join(userHome, 'ResinProjects', params.name)
|
||||
}).nodeify(callback);
|
||||
}, function(directoryName, callback) {
|
||||
params.directory = directoryName;
|
||||
return mkdirp(directoryName, callback);
|
||||
}, function(made, callback) {
|
||||
console.log("Associating " + params.name + " with " + params.directory + "...");
|
||||
process.chdir(params.directory);
|
||||
return capitano.run("app associate " + params.name + " --project " + params.directory, callback);
|
||||
}, function(remoteUrl, callback) {
|
||||
console.log("Resin git remote added: " + remoteUrl);
|
||||
console.log('Please type "git push resin master" into your project directory now!');
|
||||
return callback();
|
||||
}
|
||||
], done);
|
||||
}
|
||||
};
|
||||
|
||||
}).call(this);
|
@ -65,6 +65,8 @@
|
||||
|
||||
capitano.command(actions.help.help);
|
||||
|
||||
capitano.command(actions.wizard.wizard);
|
||||
|
||||
capitano.command(actions.auth.login);
|
||||
|
||||
capitano.command(actions.auth.logout);
|
||||
|
@ -45,11 +45,17 @@ exports.create =
|
||||
return callback(new Error('You already have an application with that name!'))
|
||||
|
||||
return callback(null, options.type) if options.type?
|
||||
resin.models.device.getSupportedDeviceTypes().then (supportedDeviceTypes) ->
|
||||
form.ask
|
||||
message: 'Device Type'
|
||||
type: 'list'
|
||||
choices: supportedDeviceTypes
|
||||
choices: [
|
||||
|
||||
# Lock to specific devices until we support
|
||||
# the rest with device specs.
|
||||
'Raspberry Pi'
|
||||
'Raspberry Pi 2'
|
||||
'BeagleBone Black'
|
||||
]
|
||||
.nodeify(callback)
|
||||
|
||||
(type, callback) ->
|
||||
|
@ -15,6 +15,8 @@ tmp = require('tmp')
|
||||
deviceConfig = require('resin-device-config')
|
||||
form = require('resin-cli-form')
|
||||
drivelist = require('drivelist')
|
||||
htmlToText = require('html-to-text')
|
||||
os = require('os')
|
||||
|
||||
# Cleanup the temporary files even when an uncaught exception occurs
|
||||
tmp.setGracefulCleanup()
|
||||
@ -365,6 +367,7 @@ exports.init =
|
||||
, callback
|
||||
|
||||
(results, callback) ->
|
||||
params.manifest = results.manifest
|
||||
console.info('Associating the device')
|
||||
|
||||
registerDevice.register pine, results.config, (error, device) ->
|
||||
@ -388,7 +391,7 @@ exports.init =
|
||||
bar = new visuals.Progress('Downloading Device OS')
|
||||
spinner = new visuals.Spinner('Downloading Device OS (size unknown)')
|
||||
|
||||
manager.configure results.manifest, results.config, (error, imagePath, removeCallback) ->
|
||||
manager.configure params.manifest, results.config, (error, imagePath, removeCallback) ->
|
||||
spinner.stop()
|
||||
return callback(error, imagePath, removeCallback)
|
||||
, (state) ->
|
||||
@ -398,6 +401,8 @@ exports.init =
|
||||
spinner.start()
|
||||
|
||||
(configuredImagePath, removeCallback, callback) ->
|
||||
console.info('The base image was cached to improve initialization time of similar devices')
|
||||
|
||||
console.info('Attempting to write operating system image to drive')
|
||||
|
||||
bar = new visuals.Progress('Writing Device OS')
|
||||
@ -420,4 +425,26 @@ exports.init =
|
||||
console.info("Device created: #{device.name}")
|
||||
return callback(null, device.name)
|
||||
|
||||
(deviceName, callback) ->
|
||||
instructions = '' if not params.manifest.instructions?
|
||||
|
||||
if _.isArray(params.manifest.instructions)
|
||||
instructions = htmlToText.fromString(params.manifest.instructions.join('\n'))
|
||||
|
||||
platformHash =
|
||||
darwin: 'osx'
|
||||
linux: 'linux'
|
||||
win32: 'windows'
|
||||
|
||||
platform = platformHash[os.platform()]
|
||||
osSpecificInstructions = params.manifest.instructions[platform]
|
||||
|
||||
if not osSpecificInstructions?
|
||||
instructions = ''
|
||||
else
|
||||
instructions = htmlToText.fromString(osSpecificInstructions.join('\n'))
|
||||
|
||||
console.log('\n' + instructions)
|
||||
return callback(null, params.uuid)
|
||||
|
||||
], done
|
||||
|
@ -1,4 +1,5 @@
|
||||
module.exports =
|
||||
wizard: require('./wizard')
|
||||
app: require('./app')
|
||||
info: require('./info')
|
||||
auth: require('./auth')
|
||||
|
122
lib/actions/wizard.coffee
Normal file
122
lib/actions/wizard.coffee
Normal file
@ -0,0 +1,122 @@
|
||||
_ = require('lodash-contrib')
|
||||
Promise = require('bluebird')
|
||||
capitano = Promise.promisifyAll(require('capitano'))
|
||||
path = require('path')
|
||||
mkdirp = require('mkdirp')
|
||||
userHome = require('user-home')
|
||||
visuals = require('resin-cli-visuals')
|
||||
async = require('async')
|
||||
resin = require('resin-sdk')
|
||||
form = require('resin-cli-form')
|
||||
|
||||
exports.wizard =
|
||||
signature: 'quickstart [name]'
|
||||
description: 'getting started with resin.io'
|
||||
help: '''
|
||||
Use this command to run a friendly wizard to get started with resin.io.
|
||||
|
||||
The wizard will guide you through:
|
||||
|
||||
- Create an application.
|
||||
- Initialise an SDCard with the resin.io operating system.
|
||||
- Associate an existing project directory with your resin.io application.
|
||||
- Push your project to your devices.
|
||||
|
||||
Examples:
|
||||
|
||||
$ sudo resin quickstart
|
||||
$ sudo resin quickstart MyApp
|
||||
'''
|
||||
root: true
|
||||
permission: 'user'
|
||||
action: (params, options, done) ->
|
||||
async.waterfall [
|
||||
|
||||
(callback) ->
|
||||
return callback() if params.name?
|
||||
|
||||
# TODO: Move this whole routine to Resin CLI Visuals
|
||||
async.waterfall [
|
||||
|
||||
(callback) ->
|
||||
resin.models.application.hasAny().nodeify(callback)
|
||||
|
||||
(hasAnyApplications, callback) ->
|
||||
return callback(null, null) if not hasAnyApplications
|
||||
|
||||
async.waterfall [
|
||||
|
||||
(callback) ->
|
||||
resin.models.application.getAll().nodeify(callback)
|
||||
|
||||
(applications, callback) ->
|
||||
applications = _.pluck(applications, 'app_name')
|
||||
applications.unshift
|
||||
name: 'Create a new application'
|
||||
value: null
|
||||
|
||||
form.ask
|
||||
message: 'Select an application'
|
||||
type: 'list'
|
||||
choices: applications
|
||||
.nodeify(callback)
|
||||
|
||||
], callback
|
||||
|
||||
(application, callback) ->
|
||||
return callback(null, application) if application?
|
||||
|
||||
form.ask
|
||||
message: 'Choose a Name for your new application'
|
||||
type: 'input'
|
||||
.then (applicationName) ->
|
||||
capitano.runAsync("app create #{applicationName}").return(applicationName)
|
||||
.nodeify(callback)
|
||||
|
||||
(applicationName, callback) ->
|
||||
params.name = applicationName
|
||||
return callback()
|
||||
|
||||
], callback
|
||||
|
||||
(callback) ->
|
||||
capitano.run("device init --application #{params.name}", callback)
|
||||
|
||||
(deviceUuid, callback) ->
|
||||
params.uuid = deviceUuid
|
||||
resin.models.device.getName(params.uuid).then (deviceName) ->
|
||||
params.deviceName = deviceName
|
||||
console.log("Waiting for #{params.deviceName} to connect to resin...")
|
||||
capitano.runAsync("device await #{params.uuid}").return(callback)
|
||||
.nodeify(callback)
|
||||
|
||||
(callback) ->
|
||||
console.log("The device #{params.deviceName} successfully connected to resin!")
|
||||
console.log('')
|
||||
capitano.run("device #{params.uuid}", callback)
|
||||
|
||||
(callback) ->
|
||||
console.log('Your device is ready, lets start pushing some code!')
|
||||
form.ask
|
||||
message: 'Please choose a directory for your code'
|
||||
type: 'input'
|
||||
|
||||
# TODO: Move this to resin-settings-client.
|
||||
default: path.join(userHome, 'ResinProjects', params.name)
|
||||
.nodeify(callback)
|
||||
|
||||
(directoryName, callback) ->
|
||||
params.directory = directoryName
|
||||
mkdirp(directoryName, callback)
|
||||
|
||||
(made, callback) ->
|
||||
console.log("Associating #{params.name} with #{params.directory}...")
|
||||
process.chdir(params.directory)
|
||||
capitano.run("app associate #{params.name} --project #{params.directory}", callback)
|
||||
|
||||
(remoteUrl, callback) ->
|
||||
console.log("Resin git remote added: #{remoteUrl}")
|
||||
console.log('Please type "git push resin master" into your project directory now!')
|
||||
return callback()
|
||||
|
||||
], done
|
@ -51,6 +51,9 @@ capitano.command(actions.info.config)
|
||||
# ---------- Help Module ----------
|
||||
capitano.command(actions.help.help)
|
||||
|
||||
# ---------- Wizard Module ----------
|
||||
capitano.command(actions.wizard.wizard)
|
||||
|
||||
# ---------- Auth Module ----------
|
||||
capitano.command(actions.auth.login)
|
||||
capitano.command(actions.auth.logout)
|
||||
|
12
package.json
12
package.json
@ -42,11 +42,13 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"async": "^1.3.0",
|
||||
"capitano": "~1.6.0",
|
||||
"bluebird": "^2.9.34",
|
||||
"capitano": "~1.6.1",
|
||||
"coffee-script": "^1.9.3",
|
||||
"conf.js": "^0.1.1",
|
||||
"drivelist": "^1.2.2",
|
||||
"fs-extra": "^0.22.1",
|
||||
"html-to-text": "^1.3.1",
|
||||
"lodash": "^3.10.0",
|
||||
"lodash-contrib": "^393.0.1",
|
||||
"mkdirp": "~0.5.0",
|
||||
@ -57,8 +59,8 @@
|
||||
"resin-cli-visuals": "^1.0.0",
|
||||
"resin-config-inject": "^2.0.0",
|
||||
"resin-device-config": "^1.0.0",
|
||||
"resin-image": "^1.1.3",
|
||||
"resin-image-manager": "^1.1.0",
|
||||
"resin-image": "^1.1.4",
|
||||
"resin-image-manager": "^2.0.0",
|
||||
"resin-pine": "^1.3.0",
|
||||
"resin-register-device": "^1.0.1",
|
||||
"resin-sdk": "^2.2.0",
|
||||
@ -67,6 +69,8 @@
|
||||
"selfupdate": "^1.1.0",
|
||||
"through2": "^2.0.0",
|
||||
"tmp": "0.0.26",
|
||||
"underscore.string": "^3.1.1"
|
||||
"underscore.string": "^3.1.1",
|
||||
"update-notifier": "^0.3.1",
|
||||
"user-home": "^2.0.0"
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user