mirror of
https://github.com/balena-io/balena-cli.git
synced 2025-01-20 11:38:57 +00:00
Merge pull request #548 from resin-io/462-noninteractive-device-init
non-interactive device init
This commit is contained in:
commit
c986e142e2
2
.gitignore
vendored
2
.gitignore
vendored
@ -31,3 +31,5 @@ resinrc.yml
|
||||
.idea
|
||||
.vscode
|
||||
.DS_Store
|
||||
|
||||
/tmp
|
||||
|
@ -11,6 +11,15 @@ This project adheres to [Semantic Versioning](http://semver.org/).
|
||||
- Added ability to run an emulated build silently with `resin build`
|
||||
- Gzip images when uploading in `resin deploy`
|
||||
- Show a clear message immediately as the deploy starts, if we're deploying an image.
|
||||
- Forced update to the newest resin-sdk (^6.4.1)
|
||||
- Allow OS version selection when doing `resin device init`
|
||||
- Actually tolerate the `--yes` param to `resin device init`
|
||||
- Allows passing `--drive` to `resin device init`
|
||||
- List detected drives with `resin util available-drives`
|
||||
- Add the `resin os build-config` method to pass the interactive config step once
|
||||
and reuse the built file for subsequent `resin os configure` calls (added the new `--config` param to it),
|
||||
and for `resin device init` (same `--config` param)
|
||||
- Improve the supported device types listing
|
||||
|
||||
### Fixed
|
||||
|
||||
|
@ -76,7 +76,7 @@ Alternatively, you can edit your configuration file and set `resinUrl: resinstag
|
||||
|
||||
The Resin CLI persists your session token, as well as cached images in `$HOME/.resin` or `%UserProfile%\_resin`.
|
||||
|
||||
Pointing the Resin CLI to persist data in another location is necessary in certain environments, like a server, where there is no home directory, or a device running Resin OS, which erases all data after a restart.
|
||||
Pointing the Resin CLI to persist data in another location is necessary in certain environments, like a server, where there is no home directory, or a device running resinOS, which erases all data after a restart.
|
||||
|
||||
You can accomplish this by setting `RESINRC_DATA_DIRECTORY=/opt/resin` or adding `dataDirectory: /opt/resin` to your configuration file, replacing `/opt/resin` with your desired directory.
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
// Generated by CoffeeScript 1.12.6
|
||||
|
||||
/*
|
||||
Copyright 2016 Resin.io
|
||||
Copyright 2016-2017 Resin.io
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
|
@ -1,7 +1,7 @@
|
||||
// Generated by CoffeeScript 1.12.6
|
||||
|
||||
/*
|
||||
Copyright 2016 Resin.io
|
||||
Copyright 2016-2017 Resin.io
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
|
@ -1,7 +1,7 @@
|
||||
// Generated by CoffeeScript 1.12.6
|
||||
|
||||
/*
|
||||
Copyright 2016 Resin.io
|
||||
Copyright 2016-2017 Resin.io
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
@ -51,6 +51,12 @@ exports.booleanDevice = {
|
||||
alias: 'd'
|
||||
};
|
||||
|
||||
exports.osVersion = {
|
||||
signature: 'version',
|
||||
description: "exact version number, or a valid semver range,\nor 'latest' (includes pre-releases),\nor 'default' (excludes pre-releases if at least one stable version is available),\nor 'recommended' (excludes pre-releases, will fail if only pre-release versions are available),\nor 'menu' (will show the interactive menu)",
|
||||
parameter: 'version'
|
||||
};
|
||||
|
||||
exports.network = {
|
||||
signature: 'network',
|
||||
parameter: 'network',
|
||||
@ -78,3 +84,17 @@ exports.forceUpdateLock = {
|
||||
boolean: true,
|
||||
alias: 'f'
|
||||
};
|
||||
|
||||
exports.drive = {
|
||||
signature: 'drive',
|
||||
description: 'the drive to write the image to, like `/dev/sdb` or `/dev/mmcblk0`. Careful with this as you can erase your hard drive. Check `resin util available-drives` for available options.',
|
||||
parameter: 'drive',
|
||||
alias: 'd'
|
||||
};
|
||||
|
||||
exports.advancedConfig = {
|
||||
signature: 'advanced',
|
||||
description: 'show advanced configuration options',
|
||||
boolean: true,
|
||||
alias: 'v'
|
||||
};
|
||||
|
@ -1,7 +1,7 @@
|
||||
// Generated by CoffeeScript 1.12.6
|
||||
|
||||
/*
|
||||
Copyright 2016 Resin.io
|
||||
Copyright 2016-2017 Resin.io
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
|
@ -1,7 +1,7 @@
|
||||
// Generated by CoffeeScript 1.12.6
|
||||
|
||||
/*
|
||||
Copyright 2016 Resin.io
|
||||
Copyright 2016-2017 Resin.io
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
@ -15,10 +15,12 @@ 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;
|
||||
var _, commandOptions;
|
||||
|
||||
commandOptions = require('./command-options');
|
||||
|
||||
_ = require('lodash');
|
||||
|
||||
exports.list = {
|
||||
signature: 'devices',
|
||||
description: 'list all devices',
|
||||
@ -27,9 +29,8 @@ exports.list = {
|
||||
permission: 'user',
|
||||
primary: true,
|
||||
action: function(params, options, done) {
|
||||
var Promise, _, resin, visuals;
|
||||
var Promise, resin, visuals;
|
||||
Promise = require('bluebird');
|
||||
_ = require('lodash');
|
||||
resin = require('resin-sdk-preconfigured');
|
||||
visuals = require('resin-cli-visuals');
|
||||
return Promise["try"](function() {
|
||||
@ -70,12 +71,12 @@ exports.supported = {
|
||||
signature: 'devices supported',
|
||||
description: 'list all supported devices',
|
||||
help: 'Use this command to get the list of all supported devices\n\nExamples:\n\n $ resin devices supported',
|
||||
permission: 'user',
|
||||
action: function(params, options, done) {
|
||||
var resin;
|
||||
var resin, visuals;
|
||||
resin = require('resin-sdk-preconfigured');
|
||||
return resin.models.config.getDeviceTypes().each(function(deviceType) {
|
||||
return console.log(deviceType.slug);
|
||||
visuals = require('resin-cli-visuals');
|
||||
return resin.models.config.getDeviceTypes().then(function(deviceTypes) {
|
||||
return console.log(visuals.table.horizontal(deviceTypes, ['slug', 'name']));
|
||||
}).nodeify(done);
|
||||
}
|
||||
};
|
||||
@ -220,9 +221,8 @@ exports.rename = {
|
||||
help: 'Use this command to rename a device.\n\nIf you omit the name, you\'ll get asked for it interactively.\n\nExamples:\n\n $ resin device rename 7cf02a6\n $ resin device rename 7cf02a6 MyPi',
|
||||
permission: 'user',
|
||||
action: function(params, options, done) {
|
||||
var Promise, _, form, resin;
|
||||
var Promise, form, resin;
|
||||
Promise = require('bluebird');
|
||||
_ = require('lodash');
|
||||
resin = require('resin-sdk-preconfigured');
|
||||
form = require('resin-cli-form');
|
||||
return Promise["try"](function() {
|
||||
@ -244,9 +244,8 @@ exports.move = {
|
||||
permission: 'user',
|
||||
options: [commandOptions.optionalApplication],
|
||||
action: function(params, options, done) {
|
||||
var _, patterns, resin;
|
||||
var patterns, resin;
|
||||
resin = require('resin-sdk-preconfigured');
|
||||
_ = require('lodash');
|
||||
patterns = require('../utils/patterns');
|
||||
return resin.models.device.get(params.uuid).then(function(device) {
|
||||
return options.application || patterns.selectApplication(function(application) {
|
||||
@ -262,14 +261,16 @@ exports.move = {
|
||||
|
||||
exports.init = {
|
||||
signature: 'device init',
|
||||
description: 'initialise a device with resin os',
|
||||
description: 'initialise a device with resinOS',
|
||||
help: 'Use this command to download the OS image of a certain application and write it to an SD Card.\n\nNotice this command may ask for confirmation interactively.\nYou can avoid this by passing the `--yes` boolean option.\n\nExamples:\n\n $ resin device init\n $ resin device init --application MyApp',
|
||||
options: [
|
||||
commandOptions.optionalApplication, commandOptions.yes, {
|
||||
signature: 'advanced',
|
||||
description: 'enable advanced configuration',
|
||||
boolean: true,
|
||||
alias: 'v'
|
||||
commandOptions.optionalApplication, commandOptions.yes, commandOptions.advancedConfig, _.assign({}, commandOptions.osVersion, {
|
||||
signature: 'os-version',
|
||||
parameter: 'os-version'
|
||||
}), commandOptions.drive, {
|
||||
signature: 'config',
|
||||
description: 'path to the config JSON file, see `resin os build-config`',
|
||||
parameter: 'config'
|
||||
}
|
||||
],
|
||||
permission: 'user',
|
||||
@ -293,7 +294,9 @@ exports.init = {
|
||||
var download;
|
||||
download = function() {
|
||||
return tmpNameAsync().then(function(tempPath) {
|
||||
return capitanoRunAsync("os download " + application.device_type + " --output '" + tempPath + "' --version default");
|
||||
var osVersion;
|
||||
osVersion = options['os-version'] || 'default';
|
||||
return capitanoRunAsync("os download " + application.device_type + " --output '" + tempPath + "' --version " + osVersion);
|
||||
}).disposer(function(tempPath) {
|
||||
return rimraf(tempPath);
|
||||
});
|
||||
@ -302,12 +305,20 @@ exports.init = {
|
||||
return capitanoRunAsync("device register " + application.app_name).then(resin.models.device.get).tap(function(device) {
|
||||
var configureCommand;
|
||||
configureCommand = "os configure '" + tempPath + "' " + device.uuid;
|
||||
if (options.advanced) {
|
||||
if (options.config) {
|
||||
configureCommand += " --config '" + options.config + "'";
|
||||
} else if (options.advanced) {
|
||||
configureCommand += ' --advanced';
|
||||
}
|
||||
return capitanoRunAsync(configureCommand).then(function() {
|
||||
var osInitCommand;
|
||||
osInitCommand = "os initialize '" + tempPath + "' --type " + application.device_type;
|
||||
if (options.yes) {
|
||||
osInitCommand += ' --yes';
|
||||
}
|
||||
if (options.drive) {
|
||||
osInitCommand += " --drive " + options.drive;
|
||||
}
|
||||
return capitanoRunAsync(osInitCommand);
|
||||
})["catch"](function(error) {
|
||||
return resin.models.device.remove(device.uuid)["finally"](function() {
|
||||
|
@ -1,7 +1,7 @@
|
||||
// Generated by CoffeeScript 1.12.6
|
||||
|
||||
/*
|
||||
Copyright 2016 Resin.io
|
||||
Copyright 2016-2017 Resin.io
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
|
@ -1,7 +1,7 @@
|
||||
// Generated by CoffeeScript 1.12.6
|
||||
|
||||
/*
|
||||
Copyright 2016 Resin.io
|
||||
Copyright 2016-2017 Resin.io
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
|
@ -1,7 +1,7 @@
|
||||
// Generated by CoffeeScript 1.12.6
|
||||
|
||||
/*
|
||||
Copyright 2016 Resin.io
|
||||
Copyright 2016-2017 Resin.io
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
@ -34,5 +34,6 @@ module.exports = {
|
||||
ssh: require('./ssh'),
|
||||
internal: require('./internal'),
|
||||
build: require('./build'),
|
||||
deploy: require('./deploy')
|
||||
deploy: require('./deploy'),
|
||||
util: require('./util')
|
||||
};
|
||||
|
@ -1,7 +1,7 @@
|
||||
// Generated by CoffeeScript 1.12.6
|
||||
|
||||
/*
|
||||
Copyright 2016 Resin.io
|
||||
Copyright 2016-2017 Resin.io
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
|
@ -1,7 +1,7 @@
|
||||
// Generated by CoffeeScript 1.12.6
|
||||
|
||||
/*
|
||||
Copyright 2016 Resin.io
|
||||
Copyright 2016-2017 Resin.io
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
|
@ -1,7 +1,7 @@
|
||||
// Generated by CoffeeScript 1.12.6
|
||||
|
||||
/*
|
||||
Copyright 2016 Resin.io
|
||||
Copyright 2016-2017 Resin.io
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
|
@ -1,7 +1,7 @@
|
||||
// Generated by CoffeeScript 1.12.6
|
||||
|
||||
/*
|
||||
Copyright 2016 Resin.io
|
||||
Copyright 2016-2017 Resin.io
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
|
@ -1,7 +1,7 @@
|
||||
// Generated by CoffeeScript 1.12.6
|
||||
|
||||
/*
|
||||
Copyright 2016 Resin.io
|
||||
Copyright 2016-2017 Resin.io
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
|
@ -1,7 +1,7 @@
|
||||
// Generated by CoffeeScript 1.12.6
|
||||
|
||||
/*
|
||||
Copyright 2016 Resin.io
|
||||
Copyright 2016-2017 Resin.io
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
|
@ -1,7 +1,7 @@
|
||||
// Generated by CoffeeScript 1.12.6
|
||||
|
||||
/*
|
||||
Copyright 2016 Resin.io
|
||||
Copyright 2016-2017 Resin.io
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
@ -15,10 +15,12 @@ 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;
|
||||
var INIT_WARNING_MESSAGE, _, buildConfig, commandOptions, formatVersion, resolveVersion;
|
||||
|
||||
commandOptions = require('./command-options');
|
||||
|
||||
_ = require('lodash');
|
||||
|
||||
formatVersion = function(v, isRecommended) {
|
||||
var result;
|
||||
result = "v" + v;
|
||||
@ -53,6 +55,23 @@ resolveVersion = function(deviceType, version) {
|
||||
});
|
||||
};
|
||||
|
||||
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));
|
||||
});
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
exports.download = {
|
||||
signature: 'os download <type>',
|
||||
description: 'download an unconfigured os image',
|
||||
@ -65,11 +84,7 @@ exports.download = {
|
||||
parameter: 'output',
|
||||
alias: 'o',
|
||||
required: 'You have to specify the output location'
|
||||
}, {
|
||||
signature: 'version',
|
||||
description: "exact version number, or a valid semver range,\nor 'latest' (includes pre-releases),\nor 'default' (excludes pre-releases if at least one stable version is available),\nor 'recommended' (excludes pre-releases, will fail if only pre-release versions are available),\nor 'menu' (will show the interactive menu)",
|
||||
parameter: 'version'
|
||||
}
|
||||
}, commandOptions.osVersion
|
||||
],
|
||||
action: function(params, options, done) {
|
||||
var Promise, displayVersion, fs, manager, rindle, unzip, visuals;
|
||||
@ -120,55 +135,93 @@ exports.download = {
|
||||
}
|
||||
};
|
||||
|
||||
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',
|
||||
buildConfig = function(image, deviceType, advanced) {
|
||||
var form, helpers;
|
||||
if (advanced == null) {
|
||||
advanced = false;
|
||||
}
|
||||
form = require('resin-cli-form');
|
||||
helpers = require('../utils/helpers');
|
||||
return helpers.getManifest(image, deviceType).get('options').then(function(questions) {
|
||||
var advancedGroup, override;
|
||||
if (!advanced) {
|
||||
advancedGroup = _.findWhere(questions, {
|
||||
name: 'advanced',
|
||||
isGroup: true
|
||||
});
|
||||
if (advancedGroup != null) {
|
||||
override = helpers.getGroupDefaults(advancedGroup);
|
||||
}
|
||||
}
|
||||
return form.run(questions, {
|
||||
override: override
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
exports.buildConfig = {
|
||||
signature: 'os build-config <image> <device-type>',
|
||||
description: 'build the OS config and save it to the JSON file',
|
||||
help: 'Use this command to prebuild the OS config once and skip the interactive part of `resin os configure`.\n\nExamples:\n\n $ resin os build-config ../path/rpi3.img raspberrypi3 --output rpi3-config.json\n $ resin os configure ../path/rpi3.img 7cf02a6 --config "$(cat rpi3-config.json)"',
|
||||
permission: 'user',
|
||||
options: [
|
||||
{
|
||||
signature: 'advanced',
|
||||
description: 'show advanced commands',
|
||||
boolean: true,
|
||||
alias: 'v'
|
||||
commandOptions.advancedConfig, {
|
||||
signature: 'output',
|
||||
description: 'the path to the output JSON file',
|
||||
alias: 'o',
|
||||
required: 'the output path is required',
|
||||
parameter: 'output'
|
||||
}
|
||||
],
|
||||
action: function(params, options, done) {
|
||||
var _, form, helpers, init, resin;
|
||||
_ = require('lodash');
|
||||
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);
|
||||
}
|
||||
}
|
||||
return form.run(questions, {
|
||||
override: override
|
||||
});
|
||||
}).then(function(answers) {
|
||||
return init.configure(params.image, params.uuid, answers).then(helpers.osProgressHandler);
|
||||
});
|
||||
var Promise, fs, writeFileAsync;
|
||||
fs = require('fs');
|
||||
Promise = require('bluebird');
|
||||
writeFileAsync = Promise.promisify(fs.writeFile);
|
||||
return buildConfig(params.image, params['device-type'], options.advanced).then(function(answers) {
|
||||
return writeFileAsync(options.output, JSON.stringify(answers, null, 4));
|
||||
}).nodeify(done);
|
||||
}
|
||||
};
|
||||
|
||||
initWarningMessage = 'Note: Initializing the device may ask for administrative permissions\nbecause we need to access the raw devices directly.';
|
||||
exports.configure = {
|
||||
signature: 'os configure <image> <uuid>',
|
||||
description: 'configure an os image',
|
||||
help: 'Use this command to configure a previously downloaded operating system image for the specific device.\n\nExamples:\n\n $ resin os configure ../path/rpi.img 7cf02a6',
|
||||
permission: 'user',
|
||||
options: [
|
||||
commandOptions.advancedConfig, {
|
||||
signature: 'config',
|
||||
description: 'path to the config JSON file, see `resin os build-config`',
|
||||
parameter: 'config'
|
||||
}
|
||||
],
|
||||
action: function(params, options, done) {
|
||||
var Promise, fs, helpers, init, readFileAsync, resin;
|
||||
fs = require('fs');
|
||||
Promise = require('bluebird');
|
||||
readFileAsync = Promise.promisify(fs.readFile);
|
||||
resin = require('resin-sdk-preconfigured');
|
||||
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) {
|
||||
if (options.config) {
|
||||
return readFileAsync(options.config, 'utf8').then(JSON.parse);
|
||||
}
|
||||
return buildConfig(params.image, device.device_type, options.advanced);
|
||||
}).then(function(answers) {
|
||||
return init.configure(params.image, params.uuid, answers).then(helpers.osProgressHandler);
|
||||
}).nodeify(done);
|
||||
}
|
||||
};
|
||||
|
||||
INIT_WARNING_MESSAGE = 'Note: Initializing the device may ask for administrative permissions\nbecause we need to access the raw devices directly.';
|
||||
|
||||
exports.initialize = {
|
||||
signature: 'os initialize <image>',
|
||||
description: 'initialize an os image',
|
||||
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'",
|
||||
help: "Use this command to initialize a device with previously configured operating system image.\n\n" + INIT_WARNING_MESSAGE + "\n\nExamples:\n\n $ resin os initialize ../path/rpi.img --type 'raspberry-pi'",
|
||||
permission: 'user',
|
||||
options: [
|
||||
commandOptions.yes, {
|
||||
@ -177,12 +230,7 @@ exports.initialize = {
|
||||
parameter: 'type',
|
||||
alias: 't',
|
||||
required: 'You have to specify a device type'
|
||||
}, {
|
||||
signature: 'drive',
|
||||
description: 'drive',
|
||||
parameter: 'drive',
|
||||
alias: 'd'
|
||||
}
|
||||
}, commandOptions.drive
|
||||
],
|
||||
action: function(params, options, done) {
|
||||
var Promise, form, helpers, patterns, umountAsync;
|
||||
@ -191,7 +239,7 @@ exports.initialize = {
|
||||
form = require('resin-cli-form');
|
||||
patterns = require('../utils/patterns');
|
||||
helpers = require('../utils/helpers');
|
||||
console.info("Initializing device\n\n" + initWarningMessage);
|
||||
console.info("Initializing device\n\n" + INIT_WARNING_MESSAGE);
|
||||
return helpers.getManifest(params.image, options.type).then(function(manifest) {
|
||||
var ref;
|
||||
return (ref = manifest.initialization) != null ? ref.options : void 0;
|
||||
@ -202,12 +250,10 @@ exports.initialize = {
|
||||
}
|
||||
});
|
||||
}).tap(function(answers) {
|
||||
var message;
|
||||
if (answers.drive == null) {
|
||||
return;
|
||||
}
|
||||
message = "This will erase " + answers.drive + ". Are you sure?";
|
||||
return patterns.confirm(options.yes, message)["return"](answers.drive).then(umountAsync);
|
||||
return patterns.confirm(options.yes, "This will erase " + answers.drive + ". Are you sure?", "Going to erase " + answers.drive + ".")["return"](answers.drive).then(umountAsync);
|
||||
}).tap(function(answers) {
|
||||
return helpers.sudo(['internal', 'osinit', params.image, options.type, JSON.stringify(answers)]);
|
||||
}).then(function(answers) {
|
||||
|
@ -1,7 +1,7 @@
|
||||
// Generated by CoffeeScript 1.12.6
|
||||
|
||||
/*
|
||||
Copyright 2016 Resin.io
|
||||
Copyright 2016-2017 Resin.io
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
|
@ -1,7 +1,7 @@
|
||||
// Generated by CoffeeScript 1.12.6
|
||||
|
||||
/*
|
||||
Copyright 2016 Resin.io
|
||||
Copyright 2016-2017 Resin.io
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
|
@ -1,7 +1,7 @@
|
||||
// Generated by CoffeeScript 1.12.6
|
||||
|
||||
/*
|
||||
Copyright 2016 Resin.io
|
||||
Copyright 2016-2017 Resin.io
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
|
57
build/actions/util.js
Normal file
57
build/actions/util.js
Normal file
@ -0,0 +1,57 @@
|
||||
// Generated by CoffeeScript 1.12.6
|
||||
|
||||
/*
|
||||
Copyright 2016-2017 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 _;
|
||||
|
||||
_ = require('lodash');
|
||||
|
||||
exports.availableDrives = {
|
||||
signature: 'util available-drives',
|
||||
description: 'list available drives',
|
||||
help: "Use this command to list your machine's drives usable for writing the OS image to.\nSkips the system drives.",
|
||||
action: function() {
|
||||
var Promise, chalk, driveListAsync, drivelist, formatDrive, getDrives, visuals;
|
||||
Promise = require('bluebird');
|
||||
drivelist = require('drivelist');
|
||||
driveListAsync = Promise.promisify(drivelist.list);
|
||||
chalk = require('chalk');
|
||||
visuals = require('resin-cli-visuals');
|
||||
formatDrive = function(drive) {
|
||||
var size;
|
||||
size = drive.size / 1000000000;
|
||||
return {
|
||||
device: drive.device,
|
||||
size: (size.toFixed(1)) + " GB",
|
||||
description: 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 console.log(visuals.table.horizontal(drives.map(formatDrive), ['device', 'size', 'description']));
|
||||
});
|
||||
}
|
||||
};
|
@ -1,7 +1,7 @@
|
||||
// Generated by CoffeeScript 1.12.6
|
||||
|
||||
/*
|
||||
Copyright 2016 Resin.io
|
||||
Copyright 2016-2017 Resin.io
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
|
@ -1,7 +1,7 @@
|
||||
// Generated by CoffeeScript 1.12.6
|
||||
|
||||
/*
|
||||
Copyright 2016 Resin.io
|
||||
Copyright 2016-2017 Resin.io
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
@ -166,8 +166,12 @@ capitano.command(actions.env.rename);
|
||||
|
||||
capitano.command(actions.env.remove);
|
||||
|
||||
capitano.command(actions.os.versions);
|
||||
|
||||
capitano.command(actions.os.download);
|
||||
|
||||
capitano.command(actions.os.buildConfig);
|
||||
|
||||
capitano.command(actions.os.configure);
|
||||
|
||||
capitano.command(actions.os.initialize);
|
||||
@ -206,6 +210,8 @@ capitano.command(actions.local.scan);
|
||||
|
||||
capitano.command(actions.local.stop);
|
||||
|
||||
capitano.command(actions.util.availableDrives);
|
||||
|
||||
capitano.command(actions.internal.osInit);
|
||||
|
||||
capitano.command(actions.build);
|
||||
|
@ -1,7 +1,7 @@
|
||||
// Generated by CoffeeScript 1.12.6
|
||||
|
||||
/*
|
||||
Copyright 2016 Resin.io
|
||||
Copyright 2016-2017 Resin.io
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
|
@ -1,7 +1,7 @@
|
||||
// Generated by CoffeeScript 1.12.6
|
||||
|
||||
/*
|
||||
Copyright 2016 Resin.io
|
||||
Copyright 2016-2017 Resin.io
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
|
@ -1,7 +1,7 @@
|
||||
// Generated by CoffeeScript 1.12.6
|
||||
|
||||
/*
|
||||
Copyright 2016 Resin.io
|
||||
Copyright 2016-2017 Resin.io
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
@ -100,9 +100,12 @@ exports.selectDeviceType = function() {
|
||||
});
|
||||
};
|
||||
|
||||
exports.confirm = function(yesOption, message) {
|
||||
exports.confirm = function(yesOption, message, yesMessage) {
|
||||
return Promise["try"](function() {
|
||||
if (yesOption) {
|
||||
if (yesMessage) {
|
||||
console.log(yesMessage);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return form.ask({
|
||||
|
@ -1,7 +1,7 @@
|
||||
// Generated by CoffeeScript 1.12.6
|
||||
|
||||
/*
|
||||
Copyright 2016 Resin.io
|
||||
Copyright 2016-2017 Resin.io
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
|
@ -1,7 +1,7 @@
|
||||
// Generated by CoffeeScript 1.12.6
|
||||
|
||||
/*
|
||||
Copyright 2016 Resin.io
|
||||
Copyright 2016-2017 Resin.io
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
|
@ -1,7 +1,7 @@
|
||||
// Generated by CoffeeScript 1.12.6
|
||||
|
||||
/*
|
||||
Copyright 2016 Resin.io
|
||||
Copyright 2016-2017 Resin.io
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
|
@ -103,5 +103,9 @@ module.exports =
|
||||
'lib/actions/build.coffee'
|
||||
'lib/actions/deploy.coffee'
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
title: 'Utilities',
|
||||
files: [ 'lib/actions/util.coffee' ]
|
||||
},
|
||||
]
|
||||
|
112
doc/automated-init.md
Normal file
112
doc/automated-init.md
Normal file
@ -0,0 +1,112 @@
|
||||
# Provisioning Resin.io devices in automated (non-interactive) mode
|
||||
|
||||
This document describes how to run the `device init` command in non-interactive mode.
|
||||
|
||||
It requires collecting some preliminary information _once_.
|
||||
|
||||
The final command to provision the device looks like this:
|
||||
|
||||
```bash
|
||||
resin device init --app APP_ID --os-version OS_VERSION --drive DRIVE --config CONFIG_FILE --yes
|
||||
|
||||
```
|
||||
|
||||
You can run this command as many times as you need, putting the new medium (SD card / USB stick) each time.
|
||||
|
||||
But before you can run it you need to collect the parameters and build the configuration file. Keep reading to figure out how to do it.
|
||||
|
||||
|
||||
## Collect all the required parameters.
|
||||
|
||||
1. `DEVICE_TYPE`. Run
|
||||
```bash
|
||||
resin devices supported
|
||||
```
|
||||
and find the _slug_ for your target device type, like _raspberrypi3_.
|
||||
|
||||
1. `APP_ID`. Create an application (`resin app create APP_NAME --type DEVICE_TYPE`) or find an existing one (`resin apps`) and notice its ID.
|
||||
|
||||
1. `OS_VERSION`. Run
|
||||
```bash
|
||||
resin os versions DEVICE_TYPE
|
||||
```
|
||||
and pick the version that you need, like _v2.0.6+rev1.prod_.
|
||||
_Note_ that even though we support _semver ranges_ it's recommended to use the exact version when doing the automated provisioning as it
|
||||
guarantees full compatibility between the steps.
|
||||
|
||||
1. `DRIVE`. Plug in your target medium (SD card or the USB stick, depending on your device type) and run
|
||||
```bash
|
||||
resin util available-drives
|
||||
```
|
||||
and get the drive name, like _/dev/sdb_ or _/dev/mmcblk0_.
|
||||
The resin CLI will not display the system drives to protect you,
|
||||
but still please check very carefully that you've picked the correct drive as it will be erased during the provisioning process.
|
||||
|
||||
Now we have all the parameters -- time to build the config file.
|
||||
|
||||
## Build the config file
|
||||
|
||||
Interactive device provisioning process often includes collecting some extra device configuration, like the networking mode and wifi credentials.
|
||||
|
||||
To skip this interactive step we need to buid this configuration once and save it to the JSON file for later reuse.
|
||||
|
||||
Let's say we will place it into the `CONFIG_FILE` path, like _./resin-os/raspberrypi3-config.json_.
|
||||
|
||||
We also need to put the OS image somewhere, let's call this path `OS_IMAGE_PATH`, it can be something like _./resin-os/raspberrypi3-v2.0.6+rev1.prod.img_.
|
||||
|
||||
1. First we need to download the OS image once. That's needed for building the config, and will speedup the subsequent operations as the downloaded OS image is placed into the local cache.
|
||||
|
||||
Run:
|
||||
```bash
|
||||
resin os download DEVICE_TYPE --output OS_IMAGE_PATH --version OS_VERSION
|
||||
```
|
||||
|
||||
1. Now we're ready to build the config:
|
||||
|
||||
```bash
|
||||
resin os build-config OS_IMAGE_PATH DEVICE_TYPE --output CONFIG_FILE
|
||||
```
|
||||
|
||||
This will run you through the interactive configuration wizard and in the end save the generated config as `CONFIG_FILE`. You can then verify it's not empty:
|
||||
|
||||
```bash
|
||||
cat CONFIG_FILE
|
||||
```
|
||||
|
||||
## Done
|
||||
|
||||
Now you're ready to run the command in the beginning of this guide.
|
||||
|
||||
Please note again that all of these steps only need to be done once (unless you need to change something), and once all the parameters are collected the main init command can be run unchanged.
|
||||
|
||||
But there are still some nuances to cover, please read below.
|
||||
|
||||
## Nuances
|
||||
|
||||
### `sudo` password on *nix systems
|
||||
|
||||
In order to write the image to the raw device we need the root permissions, this is unavoidable.
|
||||
|
||||
To improve the security we only run the minimal subcommand with `sudo`.
|
||||
|
||||
This means that with the default setup you're interrupted closer to the end of the device init process to enter your sudo password for this subcommand to work.
|
||||
|
||||
There are several ways to eliminate it and make the process fully non-interactive.
|
||||
|
||||
#### Option 1: make passwordless sudo.
|
||||
|
||||
Obviously you shouldn't do that if the machine you're working on has access to any sensitive resources or information.
|
||||
|
||||
But if you're using a machine dedicated to resin provisioning this can be fine, and also the simplest thing to do.
|
||||
|
||||
#### Option 2: `NOPASSWD` directive
|
||||
|
||||
You can configure the `resin` CLI command to be sudo-runnable without the password. Check [this post](https://askubuntu.com/questions/159007/how-do-i-run-specific-sudo-commands-without-a-password) for an example.
|
||||
|
||||
### Extra initialization config
|
||||
|
||||
As of June 2017 all the supported devices should not require any other interactive configuration.
|
||||
|
||||
But by the design of our system it is _possible_ (though it doesn't look very likely it's going to happen any time soon) that some extra initialization options may be requested for the specific device types.
|
||||
|
||||
If that is the case please raise the issue in the resin CLI repository and the maintainers will add the necessary options to build the similar JSON config for this step.
|
@ -103,7 +103,9 @@ environment variable (in the same standard URL format).
|
||||
|
||||
- OS
|
||||
|
||||
- [os versions <type>](#os-versions-60-type-62-)
|
||||
- [os download <type>](#os-download-60-type-62-)
|
||||
- [os build-config <image> <device-type>](#os-build-config-60-image-62-60-device-type-62-)
|
||||
- [os configure <image> <uuid>](#os-configure-60-image-62-60-uuid-62-)
|
||||
- [os initialize <image>](#os-initialize-60-image-62-)
|
||||
|
||||
@ -139,6 +141,10 @@ environment variable (in the same standard URL format).
|
||||
- [build [source]](#build-source-)
|
||||
- [deploy <appName> [image]](#deploy-60-appname-62-image-)
|
||||
|
||||
- Utilities
|
||||
|
||||
- [util available-drives](#util-available-drives)
|
||||
|
||||
# Application
|
||||
|
||||
## app create <name>
|
||||
@ -475,7 +481,23 @@ confirm non interactively
|
||||
|
||||
#### --advanced, -v
|
||||
|
||||
enable advanced configuration
|
||||
show advanced configuration options
|
||||
|
||||
#### --os-version <os-version>
|
||||
|
||||
exact version number, or a valid semver range,
|
||||
or 'latest' (includes pre-releases),
|
||||
or 'default' (excludes pre-releases if at least one stable version is available),
|
||||
or 'recommended' (excludes pre-releases, will fail if only pre-release versions are available),
|
||||
or 'menu' (will show the interactive menu)
|
||||
|
||||
#### --drive, -d <drive>
|
||||
|
||||
the drive to write the image to, like `/dev/sdb` or `/dev/mmcblk0`. Careful with this as you can erase your hard drive. Check `resin util available-drives` for available options.
|
||||
|
||||
#### --config <config>
|
||||
|
||||
path to the config JSON file, see `resin os build-config`
|
||||
|
||||
# Environment Variables
|
||||
|
||||
@ -813,6 +835,15 @@ device uuid
|
||||
|
||||
# OS
|
||||
|
||||
## os versions <type>
|
||||
|
||||
Use this command to show the available resinOS versions for a certain device type.
|
||||
Check available types with `resin devices supported`
|
||||
|
||||
Example:
|
||||
|
||||
$ resin os versions raspberrypi3
|
||||
|
||||
## os download <type>
|
||||
|
||||
Use this command to download an unconfigured os image for a certain device type.
|
||||
@ -848,9 +879,28 @@ or 'default' (excludes pre-releases if at least one stable version is available)
|
||||
or 'recommended' (excludes pre-releases, will fail if only pre-release versions are available),
|
||||
or 'menu' (will show the interactive menu)
|
||||
|
||||
## os build-config <image> <device-type>
|
||||
|
||||
Use this command to prebuild the OS config once and skip the interactive part of `resin os configure`.
|
||||
|
||||
Examples:
|
||||
|
||||
$ resin os build-config ../path/rpi3.img raspberrypi3 --output rpi3-config.json
|
||||
$ resin os configure ../path/rpi3.img 7cf02a6 --config "$(cat rpi3-config.json)"
|
||||
|
||||
### Options
|
||||
|
||||
#### --advanced, -v
|
||||
|
||||
show advanced configuration options
|
||||
|
||||
#### --output, -o <output>
|
||||
|
||||
the path to the output JSON file
|
||||
|
||||
## os configure <image> <uuid>
|
||||
|
||||
Use this command to configure a previously download operating system image with a device.
|
||||
Use this command to configure a previously downloaded operating system image for the specific device.
|
||||
|
||||
Examples:
|
||||
|
||||
@ -860,7 +910,11 @@ Examples:
|
||||
|
||||
#### --advanced, -v
|
||||
|
||||
show advanced commands
|
||||
show advanced configuration options
|
||||
|
||||
#### --config <config>
|
||||
|
||||
path to the config JSON file, see `resin os build-config`
|
||||
|
||||
## os initialize <image>
|
||||
|
||||
@ -885,7 +939,7 @@ device type (Check available types with `resin devices supported`)
|
||||
|
||||
#### --drive, -d <drive>
|
||||
|
||||
drive
|
||||
the drive to write the image to, like `/dev/sdb` or `/dev/mmcblk0`. Careful with this as you can erase your hard drive. Check `resin util available-drives` for available options.
|
||||
|
||||
# Config
|
||||
|
||||
@ -1419,3 +1473,10 @@ Don't use docker layer caching when building
|
||||
|
||||
Run an emulated build using Qemu
|
||||
|
||||
# Utilities
|
||||
|
||||
## util available-drives
|
||||
|
||||
Use this command to list your machine's drives usable for writing the OS image to.
|
||||
Skips the system drives.
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
###
|
||||
Copyright 2016 Resin.io
|
||||
Copyright 2016-2017 Resin.io
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
|
@ -1,5 +1,5 @@
|
||||
###
|
||||
Copyright 2016 Resin.io
|
||||
Copyright 2016-2017 Resin.io
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
|
@ -1,5 +1,5 @@
|
||||
###
|
||||
Copyright 2016 Resin.io
|
||||
Copyright 2016-2017 Resin.io
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
@ -44,6 +44,17 @@ exports.booleanDevice =
|
||||
boolean: true
|
||||
alias: 'd'
|
||||
|
||||
exports.osVersion =
|
||||
signature: 'version'
|
||||
description: """
|
||||
exact version number, or a valid semver range,
|
||||
or 'latest' (includes pre-releases),
|
||||
or 'default' (excludes pre-releases if at least one stable version is available),
|
||||
or 'recommended' (excludes pre-releases, will fail if only pre-release versions are available),
|
||||
or 'menu' (will show the interactive menu)
|
||||
"""
|
||||
parameter: 'version'
|
||||
|
||||
exports.network =
|
||||
signature: 'network'
|
||||
parameter: 'network'
|
||||
@ -67,3 +78,17 @@ exports.forceUpdateLock =
|
||||
description: 'force action if the update lock is set'
|
||||
boolean: true
|
||||
alias: 'f'
|
||||
|
||||
exports.drive =
|
||||
signature: 'drive'
|
||||
description: 'the drive to write the image to, like `/dev/sdb` or `/dev/mmcblk0`.
|
||||
Careful with this as you can erase your hard drive.
|
||||
Check `resin util available-drives` for available options.'
|
||||
parameter: 'drive'
|
||||
alias: 'd'
|
||||
|
||||
exports.advancedConfig =
|
||||
signature: 'advanced'
|
||||
description: 'show advanced configuration options'
|
||||
boolean: true
|
||||
alias: 'v'
|
||||
|
@ -1,5 +1,5 @@
|
||||
###
|
||||
Copyright 2016 Resin.io
|
||||
Copyright 2016-2017 Resin.io
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
|
@ -1,5 +1,5 @@
|
||||
###
|
||||
Copyright 2016 Resin.io
|
||||
Copyright 2016-2017 Resin.io
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
@ -15,6 +15,7 @@ limitations under the License.
|
||||
###
|
||||
|
||||
commandOptions = require('./command-options')
|
||||
_ = require('lodash')
|
||||
|
||||
exports.list =
|
||||
signature: 'devices'
|
||||
@ -36,7 +37,6 @@ exports.list =
|
||||
primary: true
|
||||
action: (params, options, done) ->
|
||||
Promise = require('bluebird')
|
||||
_ = require('lodash')
|
||||
resin = require('resin-sdk-preconfigured')
|
||||
visuals = require('resin-cli-visuals')
|
||||
|
||||
@ -114,11 +114,15 @@ exports.supported =
|
||||
|
||||
$ resin devices supported
|
||||
'''
|
||||
permission: 'user'
|
||||
action: (params, options, done) ->
|
||||
resin = require('resin-sdk-preconfigured')
|
||||
resin.models.config.getDeviceTypes().each (deviceType) ->
|
||||
console.log(deviceType.slug)
|
||||
visuals = require('resin-cli-visuals')
|
||||
|
||||
resin.models.config.getDeviceTypes().then (deviceTypes) ->
|
||||
console.log visuals.table.horizontal deviceTypes, [
|
||||
'slug'
|
||||
'name'
|
||||
]
|
||||
.nodeify(done)
|
||||
|
||||
exports.register =
|
||||
@ -305,7 +309,6 @@ exports.rename =
|
||||
permission: 'user'
|
||||
action: (params, options, done) ->
|
||||
Promise = require('bluebird')
|
||||
_ = require('lodash')
|
||||
resin = require('resin-sdk-preconfigured')
|
||||
form = require('resin-cli-form')
|
||||
|
||||
@ -336,7 +339,6 @@ exports.move =
|
||||
options: [ commandOptions.optionalApplication ]
|
||||
action: (params, options, done) ->
|
||||
resin = require('resin-sdk-preconfigured')
|
||||
_ = require('lodash')
|
||||
patterns = require('../utils/patterns')
|
||||
|
||||
resin.models.device.get(params.uuid).then (device) ->
|
||||
@ -353,7 +355,7 @@ exports.move =
|
||||
|
||||
exports.init =
|
||||
signature: 'device init'
|
||||
description: 'initialise a device with resin os'
|
||||
description: 'initialise a device with resinOS'
|
||||
help: '''
|
||||
Use this command to download the OS image of a certain application and write it to an SD Card.
|
||||
|
||||
@ -368,11 +370,13 @@ exports.init =
|
||||
options: [
|
||||
commandOptions.optionalApplication
|
||||
commandOptions.yes
|
||||
commandOptions.advancedConfig
|
||||
_.assign({}, commandOptions.osVersion, { signature: 'os-version', parameter: 'os-version' })
|
||||
commandOptions.drive
|
||||
{
|
||||
signature: 'advanced'
|
||||
description: 'enable advanced configuration'
|
||||
boolean: true
|
||||
alias: 'v'
|
||||
signature: 'config'
|
||||
description: 'path to the config JSON file, see `resin os build-config`'
|
||||
parameter: 'config'
|
||||
}
|
||||
]
|
||||
permission: 'user'
|
||||
@ -396,8 +400,8 @@ exports.init =
|
||||
|
||||
download = ->
|
||||
tmpNameAsync().then (tempPath) ->
|
||||
# TODO: allow version selection
|
||||
capitanoRunAsync("os download #{application.device_type} --output '#{tempPath}' --version default")
|
||||
osVersion = options['os-version'] or 'default'
|
||||
capitanoRunAsync("os download #{application.device_type} --output '#{tempPath}' --version #{osVersion}")
|
||||
.disposer (tempPath) ->
|
||||
return rimraf(tempPath)
|
||||
|
||||
@ -406,11 +410,17 @@ exports.init =
|
||||
.then(resin.models.device.get)
|
||||
.tap (device) ->
|
||||
configureCommand = "os configure '#{tempPath}' #{device.uuid}"
|
||||
if options.advanced
|
||||
if options.config
|
||||
configureCommand += " --config '#{options.config}'"
|
||||
else if options.advanced
|
||||
configureCommand += ' --advanced'
|
||||
capitanoRunAsync(configureCommand)
|
||||
.then ->
|
||||
osInitCommand = "os initialize '#{tempPath}' --type #{application.device_type}"
|
||||
if options.yes
|
||||
osInitCommand += ' --yes'
|
||||
if options.drive
|
||||
osInitCommand += " --drive #{options.drive}"
|
||||
capitanoRunAsync(osInitCommand)
|
||||
# Make sure the device resource is removed if there is an
|
||||
# error when configuring or initializing a device image
|
||||
|
@ -1,5 +1,5 @@
|
||||
###
|
||||
Copyright 2016 Resin.io
|
||||
Copyright 2016-2017 Resin.io
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
|
@ -1,5 +1,5 @@
|
||||
###
|
||||
Copyright 2016 Resin.io
|
||||
Copyright 2016-2017 Resin.io
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
|
@ -1,5 +1,5 @@
|
||||
###
|
||||
Copyright 2016 Resin.io
|
||||
Copyright 2016-2017 Resin.io
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
@ -34,3 +34,4 @@ module.exports =
|
||||
internal: require('./internal')
|
||||
build: require('./build')
|
||||
deploy: require('./deploy')
|
||||
util: require('./util')
|
||||
|
@ -1,5 +1,5 @@
|
||||
###
|
||||
Copyright 2016 Resin.io
|
||||
Copyright 2016-2017 Resin.io
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
|
@ -1,5 +1,5 @@
|
||||
###
|
||||
Copyright 2016 Resin.io
|
||||
Copyright 2016-2017 Resin.io
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
|
@ -1,5 +1,5 @@
|
||||
###
|
||||
Copyright 2016 Resin.io
|
||||
Copyright 2016-2017 Resin.io
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
|
@ -1,5 +1,5 @@
|
||||
###
|
||||
Copyright 2016 Resin.io
|
||||
Copyright 2016-2017 Resin.io
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
|
@ -1,5 +1,5 @@
|
||||
###
|
||||
Copyright 2016 Resin.io
|
||||
Copyright 2016-2017 Resin.io
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
|
@ -1,5 +1,5 @@
|
||||
###
|
||||
Copyright 2016 Resin.io
|
||||
Copyright 2016-2017 Resin.io
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
|
@ -1,5 +1,5 @@
|
||||
###
|
||||
Copyright 2016 Resin.io
|
||||
Copyright 2016-2017 Resin.io
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
@ -15,6 +15,7 @@ limitations under the License.
|
||||
###
|
||||
|
||||
commandOptions = require('./command-options')
|
||||
_ = require('lodash')
|
||||
|
||||
formatVersion = (v, isRecommended) ->
|
||||
result = "v#{v}"
|
||||
@ -41,6 +42,25 @@ resolveVersion = (deviceType, version) ->
|
||||
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.
|
||||
Check available types with `resin devices supported`
|
||||
|
||||
Example:
|
||||
|
||||
$ resin os versions raspberrypi3
|
||||
'''
|
||||
action: (params, options, done) ->
|
||||
resin = require('resin-sdk-preconfigured')
|
||||
|
||||
resin.models.os.getSupportedVersions(params.type)
|
||||
.then ({ versions, recommended }) ->
|
||||
versions.forEach (v) ->
|
||||
console.log(formatVersion(v, v is recommended))
|
||||
|
||||
exports.download =
|
||||
signature: 'os download <type>'
|
||||
description: 'download an unconfigured os image'
|
||||
@ -73,17 +93,7 @@ exports.download =
|
||||
alias: 'o'
|
||||
required: 'You have to specify the output location'
|
||||
}
|
||||
{
|
||||
signature: 'version'
|
||||
description: """
|
||||
exact version number, or a valid semver range,
|
||||
or 'latest' (includes pre-releases),
|
||||
or 'default' (excludes pre-releases if at least one stable version is available),
|
||||
or 'recommended' (excludes pre-releases, will fail if only pre-release versions are available),
|
||||
or 'menu' (will show the interactive menu)
|
||||
"""
|
||||
parameter: 'version'
|
||||
}
|
||||
commandOptions.osVersion
|
||||
]
|
||||
action: (params, options, done) ->
|
||||
Promise = require('bluebird')
|
||||
@ -134,11 +144,60 @@ exports.download =
|
||||
console.info('The image was downloaded successfully')
|
||||
.nodeify(done)
|
||||
|
||||
buildConfig = (image, deviceType, advanced = false) ->
|
||||
form = require('resin-cli-form')
|
||||
helpers = require('../utils/helpers')
|
||||
|
||||
helpers.getManifest(image, deviceType)
|
||||
.get('options')
|
||||
.then (questions) ->
|
||||
if not advanced
|
||||
advancedGroup = _.findWhere questions,
|
||||
name: 'advanced'
|
||||
isGroup: true
|
||||
|
||||
if advancedGroup?
|
||||
override = helpers.getGroupDefaults(advancedGroup)
|
||||
|
||||
return form.run(questions, { override })
|
||||
|
||||
exports.buildConfig =
|
||||
signature: 'os build-config <image> <device-type>'
|
||||
description: 'build the OS config and save it to the JSON file'
|
||||
help: '''
|
||||
Use this command to prebuild the OS config once and skip the interactive part of `resin os configure`.
|
||||
|
||||
Examples:
|
||||
|
||||
$ resin os build-config ../path/rpi3.img raspberrypi3 --output rpi3-config.json
|
||||
$ resin os configure ../path/rpi3.img 7cf02a6 --config "$(cat rpi3-config.json)"
|
||||
'''
|
||||
permission: 'user'
|
||||
options: [
|
||||
commandOptions.advancedConfig
|
||||
{
|
||||
signature: 'output'
|
||||
description: 'the path to the output JSON file'
|
||||
alias: 'o'
|
||||
required: 'the output path is required'
|
||||
parameter: 'output'
|
||||
}
|
||||
]
|
||||
action: (params, options, done) ->
|
||||
fs = require('fs')
|
||||
Promise = require('bluebird')
|
||||
writeFileAsync = Promise.promisify(fs.writeFile)
|
||||
|
||||
buildConfig(params.image, params['device-type'], options.advanced)
|
||||
.then (answers) ->
|
||||
writeFileAsync(options.output, JSON.stringify(answers, null, 4))
|
||||
.nodeify(done)
|
||||
|
||||
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.
|
||||
Use this command to configure a previously downloaded operating system image for the specific device.
|
||||
|
||||
Examples:
|
||||
|
||||
@ -146,38 +205,32 @@ exports.configure =
|
||||
'''
|
||||
permission: 'user'
|
||||
options: [
|
||||
signature: 'advanced'
|
||||
description: 'show advanced commands'
|
||||
boolean: true
|
||||
alias: 'v'
|
||||
commandOptions.advancedConfig
|
||||
{
|
||||
signature: 'config'
|
||||
description: 'path to the config JSON file, see `resin os build-config`'
|
||||
parameter: 'config'
|
||||
}
|
||||
]
|
||||
action: (params, options, done) ->
|
||||
_ = require('lodash')
|
||||
fs = require('fs')
|
||||
Promise = require('bluebird')
|
||||
readFileAsync = Promise.promisify(fs.readFile)
|
||||
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')
|
||||
resin.models.device.get(params.uuid).then (device) ->
|
||||
helpers.getManifest(params.image, device.device_type)
|
||||
.get('options')
|
||||
.then (questions) ->
|
||||
|
||||
if not options.advanced
|
||||
advancedGroup = _.findWhere questions,
|
||||
name: 'advanced'
|
||||
isGroup: true
|
||||
|
||||
if advancedGroup?
|
||||
override = helpers.getGroupDefaults(advancedGroup)
|
||||
|
||||
return form.run(questions, { override })
|
||||
.then (answers) ->
|
||||
init.configure(params.image, params.uuid, answers).then(helpers.osProgressHandler)
|
||||
if options.config
|
||||
return readFileAsync(options.config, 'utf8')
|
||||
.then(JSON.parse)
|
||||
return buildConfig(params.image, device.device_type, options.advanced)
|
||||
.then (answers) ->
|
||||
init.configure(params.image, params.uuid, answers).then(helpers.osProgressHandler)
|
||||
.nodeify(done)
|
||||
|
||||
initWarningMessage = '''
|
||||
INIT_WARNING_MESSAGE = '''
|
||||
Note: Initializing the device may ask for administrative permissions
|
||||
because we need to access the raw devices directly.
|
||||
'''
|
||||
@ -188,7 +241,7 @@ exports.initialize =
|
||||
help: """
|
||||
Use this command to initialize a device with previously configured operating system image.
|
||||
|
||||
#{initWarningMessage}
|
||||
#{INIT_WARNING_MESSAGE}
|
||||
|
||||
Examples:
|
||||
|
||||
@ -204,12 +257,7 @@ exports.initialize =
|
||||
alias: 't'
|
||||
required: 'You have to specify a device type'
|
||||
}
|
||||
{
|
||||
signature: 'drive'
|
||||
description: 'drive'
|
||||
parameter: 'drive'
|
||||
alias: 'd'
|
||||
}
|
||||
commandOptions.drive
|
||||
]
|
||||
action: (params, options, done) ->
|
||||
Promise = require('bluebird')
|
||||
@ -221,7 +269,7 @@ exports.initialize =
|
||||
console.info("""
|
||||
Initializing device
|
||||
|
||||
#{initWarningMessage}
|
||||
#{INIT_WARNING_MESSAGE}
|
||||
""")
|
||||
helpers.getManifest(params.image, options.type)
|
||||
.then (manifest) ->
|
||||
@ -232,8 +280,11 @@ exports.initialize =
|
||||
drive: options.drive
|
||||
.tap (answers) ->
|
||||
return if not answers.drive?
|
||||
message = "This will erase #{answers.drive}. Are you sure?"
|
||||
patterns.confirm(options.yes, message)
|
||||
patterns.confirm(
|
||||
options.yes
|
||||
"This will erase #{answers.drive}. Are you sure?"
|
||||
"Going to erase #{answers.drive}."
|
||||
)
|
||||
.return(answers.drive)
|
||||
.then(umountAsync)
|
||||
.tap (answers) ->
|
||||
|
@ -1,5 +1,5 @@
|
||||
###
|
||||
Copyright 2016 Resin.io
|
||||
Copyright 2016-2017 Resin.io
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
|
@ -1,5 +1,5 @@
|
||||
###
|
||||
Copyright 2016 Resin.io
|
||||
Copyright 2016-2017 Resin.io
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
|
@ -1,5 +1,5 @@
|
||||
###
|
||||
Copyright 2016 Resin.io
|
||||
Copyright 2016-2017 Resin.io
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
|
56
lib/actions/util.coffee
Normal file
56
lib/actions/util.coffee
Normal file
@ -0,0 +1,56 @@
|
||||
###
|
||||
Copyright 2016-2017 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.
|
||||
###
|
||||
|
||||
_ = require('lodash')
|
||||
|
||||
exports.availableDrives =
|
||||
# TODO: dedupe with https://github.com/resin-io-modules/resin-cli-visuals/blob/master/lib/widgets/drive/index.coffee
|
||||
signature: 'util available-drives'
|
||||
description: 'list available drives'
|
||||
help: """
|
||||
Use this command to list your machine's drives usable for writing the OS image to.
|
||||
Skips the system drives.
|
||||
"""
|
||||
action: ->
|
||||
Promise = require('bluebird')
|
||||
drivelist = require('drivelist')
|
||||
driveListAsync = Promise.promisify(drivelist.list)
|
||||
chalk = require('chalk')
|
||||
visuals = require('resin-cli-visuals')
|
||||
|
||||
formatDrive = (drive) ->
|
||||
size = drive.size / 1000000000
|
||||
return {
|
||||
device: drive.device
|
||||
size: "#{size.toFixed(1)} GB"
|
||||
description: drive.description
|
||||
}
|
||||
|
||||
getDrives = ->
|
||||
driveListAsync().then (drives) ->
|
||||
return _.reject(drives, system: true)
|
||||
|
||||
getDrives()
|
||||
.then (drives) ->
|
||||
if not drives.length
|
||||
console.error("#{chalk.red('x')} No available drives were detected, plug one in!")
|
||||
return
|
||||
|
||||
console.log visuals.table.horizontal drives.map(formatDrive), [
|
||||
'device'
|
||||
'size'
|
||||
'description'
|
||||
]
|
@ -1,5 +1,5 @@
|
||||
###
|
||||
Copyright 2016 Resin.io
|
||||
Copyright 2016-2017 Resin.io
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
|
@ -1,5 +1,5 @@
|
||||
###
|
||||
Copyright 2016 Resin.io
|
||||
Copyright 2016-2017 Resin.io
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
@ -135,7 +135,9 @@ capitano.command(actions.env.rename)
|
||||
capitano.command(actions.env.remove)
|
||||
|
||||
# ---------- OS Module ----------
|
||||
capitano.command(actions.os.versions)
|
||||
capitano.command(actions.os.download)
|
||||
capitano.command(actions.os.buildConfig)
|
||||
capitano.command(actions.os.configure)
|
||||
capitano.command(actions.os.initialize)
|
||||
|
||||
@ -168,6 +170,9 @@ capitano.command(actions.local.ssh)
|
||||
capitano.command(actions.local.scan)
|
||||
capitano.command(actions.local.stop)
|
||||
|
||||
# ---------- Public utils ----------
|
||||
capitano.command(actions.util.availableDrives)
|
||||
|
||||
# ---------- Internal utils ----------
|
||||
capitano.command(actions.internal.osInit)
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
###
|
||||
Copyright 2016 Resin.io
|
||||
Copyright 2016-2017 Resin.io
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
|
@ -1,5 +1,5 @@
|
||||
###
|
||||
Copyright 2016 Resin.io
|
||||
Copyright 2016-2017 Resin.io
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
|
@ -1,5 +1,5 @@
|
||||
###
|
||||
Copyright 2016 Resin.io
|
||||
Copyright 2016-2017 Resin.io
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
@ -76,9 +76,11 @@ exports.selectDeviceType = ->
|
||||
type: 'list'
|
||||
choices: deviceTypes
|
||||
|
||||
exports.confirm = (yesOption, message) ->
|
||||
exports.confirm = (yesOption, message, yesMessage) ->
|
||||
Promise.try ->
|
||||
return true if yesOption
|
||||
if yesOption
|
||||
console.log(yesMessage) if yesMessage
|
||||
return true
|
||||
return form.ask
|
||||
message: message
|
||||
type: 'confirm'
|
||||
|
@ -1,5 +1,5 @@
|
||||
###
|
||||
Copyright 2016 Resin.io
|
||||
Copyright 2016-2017 Resin.io
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
|
@ -1,5 +1,5 @@
|
||||
###
|
||||
Copyright 2016 Resin.io
|
||||
Copyright 2016-2017 Resin.io
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
|
@ -1,5 +1,5 @@
|
||||
###
|
||||
Copyright 2016 Resin.io
|
||||
Copyright 2016-2017 Resin.io
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
|
104
package-lock.json
generated
104
package-lock.json
generated
@ -4,7 +4,8 @@
|
||||
"lockfileVersion": 1,
|
||||
"dependencies": {
|
||||
"@resin.io/valid-email": {
|
||||
"version": "https://registry.npmjs.org/@resin.io/valid-email/-/valid-email-0.1.0.tgz",
|
||||
"version": "0.1.0",
|
||||
"resolved": "https://registry.npmjs.org/@resin.io/valid-email/-/valid-email-0.1.0.tgz",
|
||||
"integrity": "sha1-DnUwmoQ8AUqAqhSC+WmQYvL6UV0="
|
||||
},
|
||||
"@types/bluebird": {
|
||||
@ -419,7 +420,8 @@
|
||||
"integrity": "sha1-yz8+PHMtwPAe5wtAPzAuYddwmDg="
|
||||
},
|
||||
"bash": {
|
||||
"version": "https://registry.npmjs.org/bash/-/bash-0.0.1.tgz",
|
||||
"version": "0.0.1",
|
||||
"resolved": "https://registry.npmjs.org/bash/-/bash-0.0.1.tgz",
|
||||
"integrity": "sha1-nuDnp1K8Xu8Wi8SHGVVqdFSKrgw="
|
||||
},
|
||||
"bcrypt-pbkdf": {
|
||||
@ -933,9 +935,9 @@
|
||||
"integrity": "sha1-G3CK8JSknJoOfbyteQq6U52sEXc="
|
||||
},
|
||||
"drivelist": {
|
||||
"version": "5.0.21",
|
||||
"resolved": "https://registry.npmjs.org/drivelist/-/drivelist-5.0.21.tgz",
|
||||
"integrity": "sha1-hPsqJXXMj8LtKZbkuST0xUkAnSE=",
|
||||
"version": "5.0.22",
|
||||
"resolved": "https://registry.npmjs.org/drivelist/-/drivelist-5.0.22.tgz",
|
||||
"integrity": "sha1-ZAKaFtUwtIXXwrP3SBScm8bocfA=",
|
||||
"dependencies": {
|
||||
"lodash": {
|
||||
"version": "4.17.4",
|
||||
@ -1094,6 +1096,18 @@
|
||||
"version": "https://registry.npmjs.org/extend/-/extend-3.0.1.tgz",
|
||||
"integrity": "sha1-p1Xqe8Gt/MWjHOfnYtuq3F5jZEQ="
|
||||
},
|
||||
"external-editor": {
|
||||
"version": "2.0.4",
|
||||
"resolved": "https://registry.npmjs.org/external-editor/-/external-editor-2.0.4.tgz",
|
||||
"integrity": "sha1-HtkZnanL/i7y96MbL96LDRI2iXI=",
|
||||
"dependencies": {
|
||||
"iconv-lite": {
|
||||
"version": "0.4.17",
|
||||
"resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.17.tgz",
|
||||
"integrity": "sha1-T9qjs4rLwsAxsEXQ7c3+HsqxjI0="
|
||||
}
|
||||
}
|
||||
},
|
||||
"extglob": {
|
||||
"version": "https://registry.npmjs.org/extglob/-/extglob-0.3.2.tgz",
|
||||
"integrity": "sha1-Lhj/PS9JqydlzskCPwEdqo2DSaE=",
|
||||
@ -1337,11 +1351,13 @@
|
||||
"dev": true
|
||||
},
|
||||
"global-tunnel-ng": {
|
||||
"version": "https://registry.npmjs.org/global-tunnel-ng/-/global-tunnel-ng-2.1.0.tgz",
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/global-tunnel-ng/-/global-tunnel-ng-2.1.0.tgz",
|
||||
"integrity": "sha1-biozHrEqlLD7GK6PBANq72jqkVs=",
|
||||
"dependencies": {
|
||||
"lodash": {
|
||||
"version": "https://registry.npmjs.org/lodash/-/lodash-4.17.4.tgz",
|
||||
"version": "4.17.4",
|
||||
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.4.tgz",
|
||||
"integrity": "sha1-eCA6TRwyiuHYbcpkYONptX9AVa4="
|
||||
}
|
||||
}
|
||||
@ -1503,7 +1519,8 @@
|
||||
"dev": true
|
||||
},
|
||||
"hasbin": {
|
||||
"version": "https://registry.npmjs.org/hasbin/-/hasbin-1.2.3.tgz",
|
||||
"version": "1.2.3",
|
||||
"resolved": "https://registry.npmjs.org/hasbin/-/hasbin-1.2.3.tgz",
|
||||
"integrity": "sha1-eMWSaJPIAhXCtWiuH9P8q3omlrA="
|
||||
},
|
||||
"hawk": {
|
||||
@ -1577,16 +1594,6 @@
|
||||
"resolved": "https://registry.npmjs.org/inquirer/-/inquirer-3.1.0.tgz",
|
||||
"integrity": "sha512-JLl89yPOEoGohLjeGs3XCekeovADbrEw/WRJQYgPED6zeJWrpIsY9i9/rn+VltZox/9w94lVYqo94QfEmniB1w==",
|
||||
"dependencies": {
|
||||
"external-editor": {
|
||||
"version": "2.0.4",
|
||||
"resolved": "https://registry.npmjs.org/external-editor/-/external-editor-2.0.4.tgz",
|
||||
"integrity": "sha1-HtkZnanL/i7y96MbL96LDRI2iXI="
|
||||
},
|
||||
"iconv-lite": {
|
||||
"version": "0.4.17",
|
||||
"resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.17.tgz",
|
||||
"integrity": "sha1-T9qjs4rLwsAxsEXQ7c3+HsqxjI0="
|
||||
},
|
||||
"lodash": {
|
||||
"version": "4.17.4",
|
||||
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.4.tgz",
|
||||
@ -2840,59 +2847,73 @@
|
||||
}
|
||||
},
|
||||
"resin-cli-visuals": {
|
||||
"version": "https://registry.npmjs.org/resin-cli-visuals/-/resin-cli-visuals-1.3.1.tgz",
|
||||
"integrity": "sha1-Gfc5cGtCKO1+MGcxPSO2CnZ4K7M=",
|
||||
"version": "1.4.0",
|
||||
"resolved": "https://registry.npmjs.org/resin-cli-visuals/-/resin-cli-visuals-1.4.0.tgz",
|
||||
"integrity": "sha1-IHq827K2JpitzA4e2cN8jFfUb0I=",
|
||||
"dependencies": {
|
||||
"ansi-escapes": {
|
||||
"version": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-1.4.0.tgz",
|
||||
"version": "1.4.0",
|
||||
"resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-1.4.0.tgz",
|
||||
"integrity": "sha1-06ioOzGapneTZisT52HHkRQiMG4="
|
||||
},
|
||||
"bluebird": {
|
||||
"version": "https://registry.npmjs.org/bluebird/-/bluebird-2.11.0.tgz",
|
||||
"version": "2.11.0",
|
||||
"resolved": "https://registry.npmjs.org/bluebird/-/bluebird-2.11.0.tgz",
|
||||
"integrity": "sha1-U0uQM8AiyVecVro7Plpcqvu2UOE="
|
||||
},
|
||||
"cli-cursor": {
|
||||
"version": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-1.0.2.tgz",
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-1.0.2.tgz",
|
||||
"integrity": "sha1-ZNo/fValRBLll5S9Ytw1KV6PKYc="
|
||||
},
|
||||
"cli-width": {
|
||||
"version": "https://registry.npmjs.org/cli-width/-/cli-width-1.1.1.tgz",
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/cli-width/-/cli-width-1.1.1.tgz",
|
||||
"integrity": "sha1-pNKT72frt7iNSk1CwMzwDE0eNm0="
|
||||
},
|
||||
"figures": {
|
||||
"version": "https://registry.npmjs.org/figures/-/figures-1.7.0.tgz",
|
||||
"version": "1.7.0",
|
||||
"resolved": "https://registry.npmjs.org/figures/-/figures-1.7.0.tgz",
|
||||
"integrity": "sha1-y+Hjr/zxzUS4DK3+0o3Hk6lwHS4="
|
||||
},
|
||||
"inquirer": {
|
||||
"version": "https://registry.npmjs.org/inquirer/-/inquirer-0.11.4.tgz",
|
||||
"version": "0.11.4",
|
||||
"resolved": "https://registry.npmjs.org/inquirer/-/inquirer-0.11.4.tgz",
|
||||
"integrity": "sha1-geM3ToNhvq/y2XAWIG01nQsy+k0="
|
||||
},
|
||||
"is-fullwidth-code-point": {
|
||||
"version": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz",
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz",
|
||||
"integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs="
|
||||
},
|
||||
"mute-stream": {
|
||||
"version": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.5.tgz",
|
||||
"version": "0.0.5",
|
||||
"resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.5.tgz",
|
||||
"integrity": "sha1-j7+rsKmKJT0xhDMfno3rc3L6xsA="
|
||||
},
|
||||
"onetime": {
|
||||
"version": "https://registry.npmjs.org/onetime/-/onetime-1.1.0.tgz",
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/onetime/-/onetime-1.1.0.tgz",
|
||||
"integrity": "sha1-ofeDj4MUxRbwXs78vEzP4EtO14k="
|
||||
},
|
||||
"readline2": {
|
||||
"version": "https://registry.npmjs.org/readline2/-/readline2-1.0.1.tgz",
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/readline2/-/readline2-1.0.1.tgz",
|
||||
"integrity": "sha1-QQWWCP/BVHV7cV2ZidGZ/783LjU="
|
||||
},
|
||||
"restore-cursor": {
|
||||
"version": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-1.0.1.tgz",
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-1.0.1.tgz",
|
||||
"integrity": "sha1-NGYfRohjJ/7SmRR5FSJS35LapUE="
|
||||
},
|
||||
"run-async": {
|
||||
"version": "https://registry.npmjs.org/run-async/-/run-async-0.1.0.tgz",
|
||||
"version": "0.1.0",
|
||||
"resolved": "https://registry.npmjs.org/run-async/-/run-async-0.1.0.tgz",
|
||||
"integrity": "sha1-yK1KXhEGYeQCp9IbUw4AnyX444k="
|
||||
},
|
||||
"string-width": {
|
||||
"version": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz",
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz",
|
||||
"integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M="
|
||||
}
|
||||
}
|
||||
@ -3059,8 +3080,21 @@
|
||||
}
|
||||
},
|
||||
"resin-sdk-preconfigured": {
|
||||
"version": "https://registry.npmjs.org/resin-sdk-preconfigured/-/resin-sdk-preconfigured-6.0.1.tgz",
|
||||
"integrity": "sha1-Evg9E0lBUSDQnw3LlOIhQC6IkI4="
|
||||
"version": "6.4.1",
|
||||
"resolved": "https://registry.npmjs.org/resin-sdk-preconfigured/-/resin-sdk-preconfigured-6.4.1.tgz",
|
||||
"integrity": "sha1-rHrtfCOlB8IDgAjR1J7b2nA52Jc=",
|
||||
"dependencies": {
|
||||
"lodash": {
|
||||
"version": "4.17.4",
|
||||
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.4.tgz",
|
||||
"integrity": "sha1-eCA6TRwyiuHYbcpkYONptX9AVa4="
|
||||
},
|
||||
"resin-sdk": {
|
||||
"version": "6.4.1",
|
||||
"resolved": "https://registry.npmjs.org/resin-sdk/-/resin-sdk-6.4.1.tgz",
|
||||
"integrity": "sha1-z4La5vS6Ln9a+jmRtn1swCFXlVw="
|
||||
}
|
||||
}
|
||||
},
|
||||
"resin-settings-client": {
|
||||
"version": "https://registry.npmjs.org/resin-settings-client/-/resin-settings-client-3.6.1.tgz",
|
||||
|
@ -42,13 +42,13 @@
|
||||
"bluebird": "^3.3.3",
|
||||
"capitano": "^1.7.0",
|
||||
"chalk": "^1.1.3",
|
||||
"coffee-script": "~1.12.6",
|
||||
"coffee-script": "^1.12.6",
|
||||
"columnify": "^1.5.2",
|
||||
"denymount": "^2.2.0",
|
||||
"docker-qemu-transpose": "^0.2.1",
|
||||
"docker-toolbelt": "^1.3.3",
|
||||
"dockerode": "^2.4.2",
|
||||
"drivelist": "^5.0.21",
|
||||
"drivelist": "^5.0.22",
|
||||
"etcher-image-write": "^9.0.3",
|
||||
"global-tunnel-ng": "^2.1.0",
|
||||
"hasbin": "^1.2.3",
|
||||
@ -71,7 +71,7 @@
|
||||
"resin-cli-auth": "^1.1.3",
|
||||
"resin-cli-errors": "^1.2.0",
|
||||
"resin-cli-form": "^1.4.1",
|
||||
"resin-cli-visuals": "^1.3.0",
|
||||
"resin-cli-visuals": "^1.4.0",
|
||||
"resin-config-json": "^1.0.0",
|
||||
"resin-device-config": "^3.0.0",
|
||||
"resin-device-init": "^2.2.1",
|
||||
@ -79,7 +79,7 @@
|
||||
"resin-doodles": "0.0.1",
|
||||
"resin-image-fs": "^2.1.2",
|
||||
"resin-image-manager": "^4.1.1",
|
||||
"resin-sdk-preconfigured": "^6.0.0",
|
||||
"resin-sdk-preconfigured": "^6.4.1",
|
||||
"resin-settings-client": "^3.6.1",
|
||||
"resin-stream-logger": "^0.0.4",
|
||||
"resin-sync": "^7.0.0",
|
||||
|
Loading…
Reference in New Issue
Block a user