2016-01-04 03:58:51 +00:00
|
|
|
###
|
|
|
|
Copyright 2016 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.
|
|
|
|
###
|
|
|
|
|
2015-10-14 21:49:27 +00:00
|
|
|
commandOptions = require('./command-options')
|
2015-09-29 17:03:14 +00:00
|
|
|
|
|
|
|
exports.download =
|
|
|
|
signature: 'os download <type>'
|
|
|
|
description: 'download an unconfigured os image'
|
|
|
|
help: '''
|
|
|
|
Use this command to download an unconfigured os image for a certain device type.
|
|
|
|
|
|
|
|
Examples:
|
|
|
|
|
|
|
|
$ resin os download parallella -o ../foo/bar/parallella.img
|
|
|
|
'''
|
|
|
|
permission: 'user'
|
|
|
|
options: [
|
|
|
|
signature: 'output'
|
|
|
|
description: 'output path'
|
|
|
|
parameter: 'output'
|
|
|
|
alias: 'o'
|
|
|
|
required: 'You have to specify an output location'
|
|
|
|
]
|
|
|
|
action: (params, options, done) ->
|
2015-12-07 14:32:24 +00:00
|
|
|
unzip = require('unzip2')
|
|
|
|
fs = require('fs')
|
|
|
|
rindle = require('rindle')
|
|
|
|
manager = require('resin-image-manager')
|
|
|
|
visuals = require('resin-cli-visuals')
|
|
|
|
|
2015-09-29 17:03:14 +00:00
|
|
|
console.info("Getting device operating system for #{params.type}")
|
|
|
|
|
|
|
|
manager.get(params.type).then (stream) ->
|
|
|
|
bar = new visuals.Progress('Downloading Device OS')
|
|
|
|
spinner = new visuals.Spinner('Downloading Device OS (size unknown)')
|
|
|
|
|
|
|
|
stream.on 'progress', (state) ->
|
|
|
|
if state?
|
|
|
|
bar.update(state)
|
|
|
|
else
|
|
|
|
spinner.start()
|
|
|
|
|
|
|
|
stream.on 'end', ->
|
|
|
|
spinner.stop()
|
|
|
|
|
2015-09-30 14:16:24 +00:00
|
|
|
# We completely rely on the `mime` custom property
|
|
|
|
# to make this decision.
|
|
|
|
# The actual stream should be checked instead.
|
|
|
|
if stream.mime is 'application/zip'
|
|
|
|
output = unzip.Extract(path: options.output)
|
|
|
|
else
|
|
|
|
output = fs.createWriteStream(options.output)
|
2015-09-29 17:03:14 +00:00
|
|
|
|
2015-10-21 14:17:10 +00:00
|
|
|
return rindle.wait(stream.pipe(output)).return(options.output)
|
2015-09-29 17:03:14 +00:00
|
|
|
.tap (output) ->
|
2015-11-24 03:38:28 +00:00
|
|
|
console.info('The image was downloaded successfully')
|
2015-09-29 17:03:14 +00:00
|
|
|
.nodeify(done)
|
2015-09-29 17:36:29 +00:00
|
|
|
|
|
|
|
stepHandler = (step) ->
|
2015-12-07 14:32:24 +00:00
|
|
|
_ = require('lodash')
|
|
|
|
rindle = require('rindle')
|
|
|
|
visuals = require('resin-cli-visuals')
|
|
|
|
helpers = require('../utils/helpers')
|
|
|
|
|
2015-09-29 17:36:29 +00:00
|
|
|
step.on('stdout', _.bind(process.stdout.write, process.stdout))
|
|
|
|
step.on('stderr', _.bind(process.stderr.write, process.stderr))
|
|
|
|
|
|
|
|
step.on 'state', (state) ->
|
|
|
|
return if state.operation.command is 'burn'
|
|
|
|
console.log(helpers.stateToString(state))
|
|
|
|
|
|
|
|
bar = new visuals.Progress('Writing Device OS')
|
|
|
|
|
|
|
|
step.on('burn', _.bind(bar.update, bar))
|
|
|
|
|
2015-10-21 14:17:10 +00:00
|
|
|
return rindle.wait(step)
|
2015-09-29 17:36:29 +00:00
|
|
|
|
|
|
|
exports.configure =
|
|
|
|
signature: 'os configure <image> <uuid>'
|
|
|
|
description: 'configure an os image'
|
|
|
|
help: '''
|
|
|
|
Use this command to configure a previously download operating system image with a device.
|
|
|
|
|
|
|
|
Examples:
|
|
|
|
|
2016-01-21 14:23:40 +00:00
|
|
|
$ resin os configure ../path/rpi.img 7cf02a6
|
2015-09-29 17:36:29 +00:00
|
|
|
'''
|
|
|
|
permission: 'user'
|
2015-10-19 17:38:09 +00:00
|
|
|
options: [
|
|
|
|
signature: 'advanced'
|
|
|
|
description: 'show advanced commands'
|
|
|
|
boolean: true
|
|
|
|
alias: 'v'
|
|
|
|
]
|
2015-09-29 17:36:29 +00:00
|
|
|
action: (params, options, done) ->
|
2015-12-07 14:32:24 +00:00
|
|
|
_ = require('lodash')
|
|
|
|
resin = require('resin-sdk')
|
|
|
|
form = require('resin-cli-form')
|
|
|
|
init = require('resin-device-init')
|
|
|
|
helpers = require('../utils/helpers')
|
|
|
|
|
2015-09-29 17:36:29 +00:00
|
|
|
console.info('Configuring operating system image')
|
|
|
|
resin.models.device.get(params.uuid)
|
|
|
|
.get('device_type')
|
|
|
|
.then(resin.models.device.getManifestBySlug)
|
|
|
|
.get('options')
|
2015-10-19 17:38:09 +00:00
|
|
|
.then (questions) ->
|
|
|
|
|
|
|
|
if not options.advanced
|
|
|
|
advancedGroup = _.findWhere questions,
|
|
|
|
name: 'advanced'
|
|
|
|
isGroup: true
|
|
|
|
|
|
|
|
if advancedGroup?
|
|
|
|
override = helpers.getGroupDefaults(advancedGroup)
|
|
|
|
|
|
|
|
return form.run(questions, { override })
|
2015-09-29 17:36:29 +00:00
|
|
|
.then (answers) ->
|
|
|
|
init.configure(params.image, params.uuid, answers).then(stepHandler)
|
|
|
|
.nodeify(done)
|
2015-09-29 18:52:34 +00:00
|
|
|
|
|
|
|
exports.initialize =
|
2015-10-15 12:48:34 +00:00
|
|
|
signature: 'os initialize <image>'
|
2015-09-29 18:52:34 +00:00
|
|
|
description: 'initialize an os image'
|
|
|
|
help: '''
|
|
|
|
Use this command to initialize a previously configured operating system image.
|
|
|
|
|
|
|
|
Examples:
|
|
|
|
|
2015-10-15 12:48:34 +00:00
|
|
|
$ resin os initialize ../path/rpi.img --type 'raspberry-pi'
|
2015-09-29 18:52:34 +00:00
|
|
|
'''
|
|
|
|
permission: 'user'
|
2015-10-15 12:14:35 +00:00
|
|
|
options: [
|
|
|
|
commandOptions.yes
|
2015-10-15 12:48:34 +00:00
|
|
|
{
|
|
|
|
signature: 'type'
|
|
|
|
description: 'device type'
|
|
|
|
parameter: 'type'
|
|
|
|
alias: 't'
|
|
|
|
required: 'You have to specify a device type'
|
|
|
|
}
|
2015-10-15 12:14:35 +00:00
|
|
|
{
|
|
|
|
signature: 'drive'
|
|
|
|
description: 'drive'
|
|
|
|
parameter: 'drive'
|
|
|
|
alias: 'd'
|
|
|
|
}
|
|
|
|
]
|
2015-10-01 17:07:53 +00:00
|
|
|
root: true
|
2015-09-29 18:52:34 +00:00
|
|
|
action: (params, options, done) ->
|
2015-12-07 14:32:24 +00:00
|
|
|
Promise = require('bluebird')
|
|
|
|
umount = Promise.promisifyAll(require('umount'))
|
|
|
|
resin = require('resin-sdk')
|
|
|
|
form = require('resin-cli-form')
|
|
|
|
init = require('resin-device-init')
|
|
|
|
patterns = require('../utils/patterns')
|
|
|
|
|
2015-09-29 18:52:34 +00:00
|
|
|
console.info('Initializing device')
|
2015-10-15 12:48:34 +00:00
|
|
|
resin.models.device.getManifestBySlug(options.type)
|
2015-09-29 18:52:34 +00:00
|
|
|
.then (manifest) ->
|
|
|
|
return manifest.initialization?.options
|
2015-10-15 12:14:35 +00:00
|
|
|
.then (questions) ->
|
|
|
|
return form.run questions,
|
|
|
|
override:
|
|
|
|
drive: options.drive
|
2015-09-29 18:52:34 +00:00
|
|
|
.tap (answers) ->
|
|
|
|
return if not answers.drive?
|
|
|
|
message = "This will erase #{answers.drive}. Are you sure?"
|
|
|
|
patterns.confirm(options.yes, message)
|
|
|
|
.return(answers.drive)
|
|
|
|
.then(umount.umountAsync)
|
|
|
|
.tap (answers) ->
|
2015-10-15 12:48:34 +00:00
|
|
|
return init.initialize(params.image, options.type, answers).then(stepHandler)
|
2015-09-29 18:52:34 +00:00
|
|
|
.then (answers) ->
|
|
|
|
return if not answers.drive?
|
|
|
|
umount.umountAsync(answers.drive).tap ->
|
|
|
|
console.info("You can safely remove #{answers.drive} now")
|
|
|
|
.nodeify(done)
|