balena-cli/build/actions/os.js

268 lines
10 KiB
JavaScript
Raw Normal View History

2017-06-08 10:52:47 +00:00
// Generated by CoffeeScript 1.12.6
/*
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.
*/
var _, commandOptions, formatVersion, initWarningMessage, resolveVersion;
2017-03-22 09:46:06 +00:00
commandOptions = require('./command-options');
_ = require('lodash');
2017-03-22 10:50:06 +00:00
formatVersion = function(v, isRecommended) {
var result;
result = "v" + v;
if (isRecommended) {
result += ' (recommended)';
}
return result;
};
resolveVersion = function(deviceType, version) {
var form, resin;
if (version !== 'menu') {
return Promise.resolve(version);
}
form = require('resin-cli-form');
resin = require('resin-sdk-preconfigured');
return resin.models.os.getSupportedVersions(deviceType).then(function(arg) {
var choices, recommended, versions;
versions = arg.versions, recommended = arg.recommended;
choices = versions.map(function(v) {
return {
value: v,
name: formatVersion(v, v === recommended)
};
});
return form.ask({
message: 'Select the OS version:',
type: 'list',
choices: choices,
"default": recommended
});
});
};
exports.versions = {
signature: 'os versions <type>',
description: 'show the available resinOS versions for the given device type',
help: 'Use this command to show the available resinOS versions for a certain device type.\nCheck available types with `resin devices supported`\n\nExample:\n\n $ resin os versions raspberrypi3',
action: function(params, options, done) {
var resin;
resin = require('resin-sdk-preconfigured');
return resin.models.os.getSupportedVersions(params.type).then(function(arg) {
var recommended, versions;
versions = arg.versions, recommended = arg.recommended;
return versions.forEach(function(v) {
return console.log(formatVersion(v, v === recommended));
});
});
}
};
2017-03-22 09:46:06 +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.\nCheck available types with `resin devices supported`\n\nIf version is not specified the newest stable (non-pre-release) version of OS\nis downloaded if available, or the newest version otherwise (if all existing\nversions for the given device type are pre-release).\n\nYou can pass `--version menu` to pick the OS version from the interactive menu\nof all available versions.\n\nExamples:\n\n $ resin os download raspberrypi3 -o ../foo/bar/raspberry-pi.img\n $ resin os download raspberrypi3 -o ../foo/bar/raspberry-pi.img --version 1.24.1\n $ resin os download raspberrypi3 -o ../foo/bar/raspberry-pi.img --version ^1.20.0\n $ resin os download raspberrypi3 -o ../foo/bar/raspberry-pi.img --version latest\n $ resin os download raspberrypi3 -o ../foo/bar/raspberry-pi.img --version default\n $ resin os download raspberrypi3 -o ../foo/bar/raspberry-pi.img --version menu',
2017-03-22 09:46:06 +00:00
permission: 'user',
options: [
{
signature: 'output',
description: 'output path',
parameter: 'output',
alias: 'o',
required: 'You have to specify the output location'
}, commandOptions.osVersion
2017-03-22 09:46:06 +00:00
],
action: function(params, options, done) {
2017-03-22 10:50:06 +00:00
var Promise, displayVersion, fs, manager, rindle, unzip, visuals;
Promise = require('bluebird');
2017-03-22 09:46:06 +00:00
unzip = require('unzip2');
fs = require('fs');
rindle = require('rindle');
2017-03-22 09:46:06 +00:00
manager = require('resin-image-manager');
visuals = require('resin-cli-visuals');
2017-03-22 09:46:06 +00:00
console.info("Getting device operating system for " + params.type);
2017-03-22 10:50:06 +00:00
displayVersion = '';
return Promise["try"](function() {
if (!options.version) {
console.warn('OS version is not specified, using the default version: the newest stable (non-pre-release) version if available, or the newest version otherwise (if all existing versions for the given device type are pre-release).');
return 'default';
}
return resolveVersion(params.type, options.version);
}).then(function(version) {
if (version !== 'default') {
displayVersion = " " + version;
}
return manager.get(params.type, version);
}).then(function(stream) {
2017-03-22 09:46:06 +00:00
var bar, output, spinner;
2017-03-22 10:28:46 +00:00
bar = new visuals.Progress("Downloading Device OS" + displayVersion);
spinner = new visuals.Spinner("Downloading Device OS" + displayVersion + " (size unknown)");
2017-03-22 09:46:06 +00:00
stream.on('progress', function(state) {
if (state != null) {
return bar.update(state);
} else {
return spinner.start();
}
});
stream.on('end', function() {
return spinner.stop();
});
if (stream.mime === 'application/zip') {
output = unzip.Extract({
path: options.output
});
} else {
output = fs.createWriteStream(options.output);
}
2017-03-22 09:46:06 +00:00
return rindle.wait(stream.pipe(output))["return"](options.output);
}).tap(function(output) {
return console.info('The image was downloaded successfully');
}).nodeify(done);
}
};
2017-03-22 09:46:06 +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.\n\nExamples:\n\n $ resin os configure ../path/rpi.img 7cf02a6',
permission: 'user',
options: [
{
signature: 'advanced',
description: 'show advanced commands',
boolean: true,
alias: 'v'
}
],
action: function(params, options, done) {
var form, helpers, init, resin;
2017-03-22 09:46:06 +00:00
resin = require('resin-sdk-preconfigured');
form = require('resin-cli-form');
init = require('resin-device-init');
helpers = require('../utils/helpers');
console.info('Configuring operating system image');
return resin.models.device.get(params.uuid).then(function(device) {
return helpers.getManifest(params.image, device.device_type).get('options').then(function(questions) {
var advancedGroup, override;
if (!options.advanced) {
advancedGroup = _.findWhere(questions, {
name: 'advanced',
isGroup: true
});
if (advancedGroup != null) {
override = helpers.getGroupDefaults(advancedGroup);
}
}
2017-03-22 09:46:06 +00:00
return form.run(questions, {
override: override
});
2017-03-22 09:46:06 +00:00
}).then(function(answers) {
2017-03-24 09:48:14 +00:00
return init.configure(params.image, params.uuid, answers).then(helpers.osProgressHandler);
2017-03-22 09:46:06 +00:00
});
}).nodeify(done);
}
};
2017-03-24 09:48:14 +00:00
initWarningMessage = 'Note: Initializing the device may ask for administrative permissions\nbecause we need to access the raw devices directly.';
exports.availableDrives = {
signature: 'os available-drives',
description: 'list available drives',
action: function() {
var Promise, chalk, driveListAsync, drivelist, formatDrive, getDrives;
Promise = require('bluebird');
drivelist = require('drivelist');
driveListAsync = Promise.promisify(drivelist.list);
chalk = require('chalk');
formatDrive = function(drive) {
var size;
size = drive.size / 1000000000;
return drive.device + " (" + (size.toFixed(1)) + " GB) - " + drive.description;
};
getDrives = function() {
return driveListAsync().then(function(drives) {
return _.reject(drives, {
system: true
});
});
};
return getDrives().then(function(drives) {
if (!drives.length) {
console.error((chalk.red('x')) + " No available drives were detected, plug one in!");
return;
}
return drives.forEach(function(drive) {
return console.log(formatDrive(drive));
});
});
}
};
2017-03-22 09:46:06 +00:00
exports.initialize = {
signature: 'os initialize <image>',
description: 'initialize an os image',
2017-03-24 09:48:14 +00:00
help: "Use this command to initialize a device with previously configured operating system image.\n\n" + initWarningMessage + "\n\nExamples:\n\n $ resin os initialize ../path/rpi.img --type 'raspberry-pi'",
2017-03-22 09:46:06 +00:00
permission: 'user',
options: [
commandOptions.yes, {
signature: 'type',
description: 'device type (Check available types with `resin devices supported`)',
2017-03-22 09:46:06 +00:00
parameter: 'type',
alias: 't',
required: 'You have to specify a device type'
}, {
signature: 'drive',
description: 'drive to write the image to. Check `resin os available-drives` for available options.',
2017-03-22 09:46:06 +00:00
parameter: 'drive',
alias: 'd'
}
],
action: function(params, options, done) {
var Promise, form, helpers, patterns, umountAsync;
2017-03-22 09:46:06 +00:00
Promise = require('bluebird');
umountAsync = Promise.promisify(require('umount').umount);
2017-03-22 09:46:06 +00:00
form = require('resin-cli-form');
patterns = require('../utils/patterns');
helpers = require('../utils/helpers');
2017-03-24 09:48:14 +00:00
console.info("Initializing device\n\n" + initWarningMessage);
2017-03-22 09:46:06 +00:00
return helpers.getManifest(params.image, options.type).then(function(manifest) {
var ref;
return (ref = manifest.initialization) != null ? ref.options : void 0;
}).then(function(questions) {
return form.run(questions, {
override: {
drive: options.drive
}
});
}).tap(function(answers) {
if (answers.drive == null) {
return;
}
return patterns.confirm(options.yes, "This will erase " + answers.drive + ". Are you sure?", "Going to erase " + answers.drive + ".")["return"](answers.drive).then(umountAsync);
2017-03-22 09:46:06 +00:00
}).tap(function(answers) {
2017-03-24 09:48:14 +00:00
return helpers.sudo(['internal', 'osinit', params.image, options.type, JSON.stringify(answers)]);
2017-03-22 09:46:06 +00:00
}).then(function(answers) {
if (answers.drive == null) {
return;
}
return umountAsync(answers.drive).tap(function() {
2017-03-22 09:46:06 +00:00
return console.info("You can safely remove " + answers.drive + " now");
});
}).nodeify(done);
}
};