mirror of
https://github.com/balena-io/balena-cli.git
synced 2024-12-19 05:37:51 +00:00
Auto-merge for PR #720 via VersionBot
Start adding TypeScript to the CLI and stop committing build output
This commit is contained in:
commit
f106b95be2
2
.gitignore
vendored
2
.gitignore
vendored
@ -25,6 +25,7 @@ build/Release
|
||||
node_modules
|
||||
|
||||
npm-shrinkwrap.json
|
||||
package-lock.json
|
||||
.resinconf
|
||||
resinrc.yml
|
||||
|
||||
@ -33,3 +34,4 @@ resinrc.yml
|
||||
.DS_Store
|
||||
|
||||
/tmp
|
||||
build/
|
||||
|
@ -1,5 +0,0 @@
|
||||
tests
|
||||
doc
|
||||
lib
|
||||
extras
|
||||
tmp
|
@ -4,6 +4,11 @@ All notable changes to this project will be documented in this file
|
||||
automatically by Versionist. DO NOT EDIT THIS FILE MANUALLY!
|
||||
This project adheres to [Semantic Versioning](http://semver.org/).
|
||||
|
||||
## v6.10.1 - 2017-11-27
|
||||
|
||||
* Set up TypeScript compilation, and make a small start on converting the CLI #720 [Tim Perry]
|
||||
* Don't commit raw JS build output #720 [Tim Perry]
|
||||
|
||||
## v6.10.0 - 2017-11-17
|
||||
|
||||
* Allow `os configure` to configure for an app, not just a specific device #718 [Tim Perry]
|
||||
|
@ -1,111 +0,0 @@
|
||||
// Generated by CoffeeScript 1.12.7
|
||||
|
||||
/*
|
||||
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 commandOptions;
|
||||
|
||||
commandOptions = require('./command-options');
|
||||
|
||||
exports.create = {
|
||||
signature: 'app create <name>',
|
||||
description: 'create an application',
|
||||
help: 'Use this command to create a new resin.io application.\n\nYou can specify the application device type with the `--type` option.\nOtherwise, an interactive dropdown will be shown for you to select from.\n\nYou can see a list of supported device types with\n\n $ resin devices supported\n\nExamples:\n\n $ resin app create MyApp\n $ resin app create MyApp --type raspberry-pi',
|
||||
options: [
|
||||
{
|
||||
signature: 'type',
|
||||
parameter: 'type',
|
||||
description: 'application device type (Check available types with `resin devices supported`)',
|
||||
alias: 't'
|
||||
}
|
||||
],
|
||||
permission: 'user',
|
||||
action: function(params, options, done) {
|
||||
var patterns, resin;
|
||||
resin = require('resin-sdk-preconfigured');
|
||||
patterns = require('../utils/patterns');
|
||||
return resin.models.application.has(params.name).then(function(hasApplication) {
|
||||
if (hasApplication) {
|
||||
throw new Error('You already have an application with that name!');
|
||||
}
|
||||
}).then(function() {
|
||||
return options.type || patterns.selectDeviceType();
|
||||
}).then(function(deviceType) {
|
||||
return resin.models.application.create(params.name, deviceType);
|
||||
}).then(function(application) {
|
||||
return console.info("Application created: " + application.app_name + " (" + application.device_type + ", id " + application.id + ")");
|
||||
}).nodeify(done);
|
||||
}
|
||||
};
|
||||
|
||||
exports.list = {
|
||||
signature: 'apps',
|
||||
description: 'list all applications',
|
||||
help: 'Use this command to list all your applications.\n\nNotice this command only shows the most important bits of information for each app.\nIf you want detailed information, use resin app <name> instead.\n\nExamples:\n\n $ resin apps',
|
||||
permission: 'user',
|
||||
primary: true,
|
||||
action: function(params, options, done) {
|
||||
var resin, visuals;
|
||||
resin = require('resin-sdk-preconfigured');
|
||||
visuals = require('resin-cli-visuals');
|
||||
return resin.models.application.getAll().then(function(applications) {
|
||||
return console.log(visuals.table.horizontal(applications, ['id', 'app_name', 'device_type', 'online_devices', 'devices_length']));
|
||||
}).nodeify(done);
|
||||
}
|
||||
};
|
||||
|
||||
exports.info = {
|
||||
signature: 'app <name>',
|
||||
description: 'list a single application',
|
||||
help: 'Use this command to show detailed information for a single application.\n\nExamples:\n\n $ resin app MyApp',
|
||||
permission: 'user',
|
||||
primary: true,
|
||||
action: function(params, options, done) {
|
||||
var resin, visuals;
|
||||
resin = require('resin-sdk-preconfigured');
|
||||
visuals = require('resin-cli-visuals');
|
||||
return resin.models.application.get(params.name).then(function(application) {
|
||||
return console.log(visuals.table.vertical(application, ["$" + application.app_name + "$", 'id', 'device_type', 'git_repository', 'commit']));
|
||||
}).nodeify(done);
|
||||
}
|
||||
};
|
||||
|
||||
exports.restart = {
|
||||
signature: 'app restart <name>',
|
||||
description: 'restart an application',
|
||||
help: 'Use this command to restart all devices that belongs to a certain application.\n\nExamples:\n\n $ resin app restart MyApp',
|
||||
permission: 'user',
|
||||
action: function(params, options, done) {
|
||||
var resin;
|
||||
resin = require('resin-sdk-preconfigured');
|
||||
return resin.models.application.restart(params.name).nodeify(done);
|
||||
}
|
||||
};
|
||||
|
||||
exports.remove = {
|
||||
signature: 'app rm <name>',
|
||||
description: 'remove an application',
|
||||
help: 'Use this command to remove a resin.io application.\n\nNotice this command asks for confirmation interactively.\nYou can avoid this by passing the `--yes` boolean option.\n\nExamples:\n\n $ resin app rm MyApp\n $ resin app rm MyApp --yes',
|
||||
options: [commandOptions.yes],
|
||||
permission: 'user',
|
||||
action: function(params, options, done) {
|
||||
var patterns, resin;
|
||||
resin = require('resin-sdk-preconfigured');
|
||||
patterns = require('../utils/patterns');
|
||||
return patterns.confirm(options.yes, 'Are you sure you want to delete the application?').then(function() {
|
||||
return resin.models.application.remove(params.name);
|
||||
}).nodeify(done);
|
||||
}
|
||||
};
|
@ -1,157 +0,0 @@
|
||||
// Generated by CoffeeScript 1.12.7
|
||||
|
||||
/*
|
||||
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.
|
||||
*/
|
||||
exports.login = {
|
||||
signature: 'login',
|
||||
description: 'login to resin.io',
|
||||
help: 'Use this command to login to your resin.io account.\n\nThis command will prompt you to login using the following login types:\n\n- Web authorization: open your web browser and prompt you to authorize the CLI\nfrom the dashboard.\n\n- Credentials: using email/password and 2FA.\n\n- Token: using the authentication token from the preferences page.\n\nExamples:\n\n $ resin login\n $ resin login --web\n $ resin login --token "..."\n $ resin login --credentials\n $ resin login --credentials --email johndoe@gmail.com --password secret',
|
||||
options: [
|
||||
{
|
||||
signature: 'token',
|
||||
description: 'auth token',
|
||||
parameter: 'token',
|
||||
alias: 't'
|
||||
}, {
|
||||
signature: 'web',
|
||||
description: 'web-based login',
|
||||
boolean: true,
|
||||
alias: 'w'
|
||||
}, {
|
||||
signature: 'credentials',
|
||||
description: 'credential-based login',
|
||||
boolean: true,
|
||||
alias: 'c'
|
||||
}, {
|
||||
signature: 'email',
|
||||
parameter: 'email',
|
||||
description: 'email',
|
||||
alias: ['e', 'u']
|
||||
}, {
|
||||
signature: 'password',
|
||||
parameter: 'password',
|
||||
description: 'password',
|
||||
alias: 'p'
|
||||
}
|
||||
],
|
||||
primary: true,
|
||||
action: function(params, options, done) {
|
||||
var Promise, _, auth, form, login, messages, patterns, resin;
|
||||
_ = require('lodash');
|
||||
Promise = require('bluebird');
|
||||
resin = require('resin-sdk-preconfigured');
|
||||
auth = require('resin-cli-auth');
|
||||
form = require('resin-cli-form');
|
||||
patterns = require('../utils/patterns');
|
||||
messages = require('../utils/messages');
|
||||
login = function(options) {
|
||||
if (options.token != null) {
|
||||
return Promise["try"](function() {
|
||||
if (_.isString(options.token)) {
|
||||
return options.token;
|
||||
}
|
||||
return form.ask({
|
||||
message: 'Token (from the preferences page)',
|
||||
name: 'token',
|
||||
type: 'input'
|
||||
});
|
||||
}).then(resin.auth.loginWithToken);
|
||||
} else if (options.credentials) {
|
||||
return patterns.authenticate(options);
|
||||
} else if (options.web) {
|
||||
console.info('Connecting to the web dashboard');
|
||||
return auth.login();
|
||||
}
|
||||
return patterns.askLoginType().then(function(loginType) {
|
||||
var capitanoRunAsync;
|
||||
if (loginType === 'register') {
|
||||
capitanoRunAsync = Promise.promisify(require('capitano').run);
|
||||
return capitanoRunAsync('signup');
|
||||
}
|
||||
options[loginType] = true;
|
||||
return login(options);
|
||||
});
|
||||
};
|
||||
return resin.settings.get('resinUrl').then(function(resinUrl) {
|
||||
console.log(messages.resinAsciiArt);
|
||||
console.log("\nLogging in to " + resinUrl);
|
||||
return login(options);
|
||||
}).then(resin.auth.whoami).tap(function(username) {
|
||||
console.info("Successfully logged in as: " + username);
|
||||
return console.info("\nFind out about the available commands by running:\n\n $ resin help\n\n" + messages.reachingOut);
|
||||
}).nodeify(done);
|
||||
}
|
||||
};
|
||||
|
||||
exports.logout = {
|
||||
signature: 'logout',
|
||||
description: 'logout from resin.io',
|
||||
help: 'Use this command to logout from your resin.io account.o\n\nExamples:\n\n $ resin logout',
|
||||
permission: 'user',
|
||||
action: function(params, options, done) {
|
||||
var resin;
|
||||
resin = require('resin-sdk-preconfigured');
|
||||
return resin.auth.logout().nodeify(done);
|
||||
}
|
||||
};
|
||||
|
||||
exports.signup = {
|
||||
signature: 'signup',
|
||||
description: 'signup to resin.io',
|
||||
help: 'Use this command to signup for a resin.io account.\n\nIf signup is successful, you\'ll be logged in to your new user automatically.\n\nExamples:\n\n $ resin signup\n Email: johndoe@acme.com\n Password: ***********\n\n $ resin whoami\n johndoe',
|
||||
action: function(params, options, done) {
|
||||
var form, resin, validation;
|
||||
resin = require('resin-sdk-preconfigured');
|
||||
form = require('resin-cli-form');
|
||||
validation = require('../utils/validation');
|
||||
return resin.settings.get('resinUrl').then(function(resinUrl) {
|
||||
console.log("\nRegistering to " + resinUrl);
|
||||
return form.run([
|
||||
{
|
||||
message: 'Email:',
|
||||
name: 'email',
|
||||
type: 'input',
|
||||
validate: validation.validateEmail
|
||||
}, {
|
||||
message: 'Password:',
|
||||
name: 'password',
|
||||
type: 'password',
|
||||
validate: validation.validatePassword
|
||||
}
|
||||
]);
|
||||
}).then(resin.auth.register).then(resin.auth.loginWithToken).nodeify(done);
|
||||
}
|
||||
};
|
||||
|
||||
exports.whoami = {
|
||||
signature: 'whoami',
|
||||
description: 'get current username and email address',
|
||||
help: 'Use this command to find out the current logged in username and email address.\n\nExamples:\n\n $ resin whoami',
|
||||
permission: 'user',
|
||||
action: function(params, options, done) {
|
||||
var Promise, resin, visuals;
|
||||
Promise = require('bluebird');
|
||||
resin = require('resin-sdk-preconfigured');
|
||||
visuals = require('resin-cli-visuals');
|
||||
return Promise.props({
|
||||
username: resin.auth.whoami(),
|
||||
email: resin.auth.getEmail(),
|
||||
url: resin.settings.get('resinUrl')
|
||||
}).then(function(results) {
|
||||
return console.log(visuals.table.vertical(results, ['$account information$', 'username', 'email', 'url']));
|
||||
}).nodeify(done);
|
||||
}
|
||||
};
|
@ -1,50 +0,0 @@
|
||||
// Generated by CoffeeScript 1.12.7
|
||||
var Promise, dockerUtils, getBundleInfo;
|
||||
|
||||
Promise = require('bluebird');
|
||||
|
||||
dockerUtils = require('../utils/docker');
|
||||
|
||||
getBundleInfo = Promise.method(function(options) {
|
||||
var helpers;
|
||||
helpers = require('../utils/helpers');
|
||||
if (options.application != null) {
|
||||
return helpers.getAppInfo(options.application).then(function(app) {
|
||||
return [app.arch, app.device_type];
|
||||
});
|
||||
} else if ((options.arch != null) && (options.deviceType != null)) {
|
||||
return [options.arch, options.deviceType];
|
||||
} else {
|
||||
return void 0;
|
||||
}
|
||||
});
|
||||
|
||||
module.exports = {
|
||||
signature: 'build [source]',
|
||||
description: 'Build a container locally',
|
||||
permission: 'user',
|
||||
help: 'Use this command to build a container with a provided docker daemon.\n\nYou must provide either an application or a device-type/architecture\npair to use the resin Dockerfile pre-processor\n(e.g. Dockerfile.template -> Dockerfile).\n\nExamples:\n\n $ resin build\n $ resin build ./source/\n $ resin build --deviceType raspberrypi3 --arch armhf\n $ resin build --application MyApp ./source/\n $ resin build --docker \'/var/run/docker.sock\'\n $ resin build --dockerHost my.docker.host --dockerPort 2376 --ca ca.pem --key key.pem --cert cert.pem',
|
||||
options: dockerUtils.appendOptions([
|
||||
{
|
||||
signature: 'arch',
|
||||
parameter: 'arch',
|
||||
description: 'The architecture to build for',
|
||||
alias: 'A'
|
||||
}, {
|
||||
signature: 'deviceType',
|
||||
parameter: 'deviceType',
|
||||
description: 'The type of device this build is for',
|
||||
alias: 'd'
|
||||
}, {
|
||||
signature: 'application',
|
||||
parameter: 'application',
|
||||
description: 'The target resin.io application this build is for',
|
||||
alias: 'a'
|
||||
}
|
||||
]),
|
||||
action: function(params, options, done) {
|
||||
var Logger;
|
||||
Logger = require('../utils/logger');
|
||||
return dockerUtils.runBuild(params, options, getBundleInfo, new Logger()).asCallback(done);
|
||||
}
|
||||
};
|
@ -1,107 +0,0 @@
|
||||
// Generated by CoffeeScript 1.12.7
|
||||
|
||||
/*
|
||||
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.yes = {
|
||||
signature: 'yes',
|
||||
description: 'confirm non interactively',
|
||||
boolean: true,
|
||||
alias: 'y'
|
||||
};
|
||||
|
||||
exports.optionalApplication = {
|
||||
signature: 'application',
|
||||
parameter: 'application',
|
||||
description: 'application name',
|
||||
alias: ['a', 'app']
|
||||
};
|
||||
|
||||
exports.application = _.defaults({
|
||||
required: 'You have to specify an application'
|
||||
}, exports.optionalApplication);
|
||||
|
||||
exports.optionalDevice = {
|
||||
signature: 'device',
|
||||
parameter: 'device',
|
||||
description: 'device uuid',
|
||||
alias: 'd'
|
||||
};
|
||||
|
||||
exports.optionalDeviceApiKey = {
|
||||
signature: 'deviceApiKey',
|
||||
description: 'custom device key - note that this is only supported on ResinOS 2.0.3+',
|
||||
parameter: 'device-api-key',
|
||||
alias: 'k'
|
||||
};
|
||||
|
||||
exports.booleanDevice = {
|
||||
signature: 'device',
|
||||
description: 'device',
|
||||
boolean: true,
|
||||
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',
|
||||
description: 'network type',
|
||||
alias: 'n'
|
||||
};
|
||||
|
||||
exports.wifiSsid = {
|
||||
signature: 'ssid',
|
||||
parameter: 'ssid',
|
||||
description: 'wifi ssid, if network is wifi',
|
||||
alias: 's'
|
||||
};
|
||||
|
||||
exports.wifiKey = {
|
||||
signature: 'key',
|
||||
parameter: 'key',
|
||||
description: 'wifi key, if network is wifi',
|
||||
alias: 'k'
|
||||
};
|
||||
|
||||
exports.forceUpdateLock = {
|
||||
signature: 'force',
|
||||
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,261 +0,0 @@
|
||||
// Generated by CoffeeScript 1.12.7
|
||||
|
||||
/*
|
||||
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 commandOptions;
|
||||
|
||||
commandOptions = require('./command-options');
|
||||
|
||||
exports.read = {
|
||||
signature: 'config read',
|
||||
description: 'read a device configuration',
|
||||
help: 'Use this command to read the config.json file from the mounted filesystem (e.g. SD card) of a provisioned device"\n\nExamples:\n\n $ resin config read --type raspberry-pi\n $ resin config read --type raspberry-pi --drive /dev/disk2',
|
||||
options: [
|
||||
{
|
||||
signature: 'type',
|
||||
description: 'device type (Check available types with `resin devices supported`)',
|
||||
parameter: 'type',
|
||||
alias: 't',
|
||||
required: 'You have to specify a device type'
|
||||
}, {
|
||||
signature: 'drive',
|
||||
description: 'drive',
|
||||
parameter: 'drive',
|
||||
alias: 'd'
|
||||
}
|
||||
],
|
||||
permission: 'user',
|
||||
root: true,
|
||||
action: function(params, options, done) {
|
||||
var Promise, config, prettyjson, umountAsync, visuals;
|
||||
Promise = require('bluebird');
|
||||
config = require('resin-config-json');
|
||||
visuals = require('resin-cli-visuals');
|
||||
umountAsync = Promise.promisify(require('umount').umount);
|
||||
prettyjson = require('prettyjson');
|
||||
return Promise["try"](function() {
|
||||
return options.drive || visuals.drive('Select the device drive');
|
||||
}).tap(umountAsync).then(function(drive) {
|
||||
return config.read(drive, options.type);
|
||||
}).tap(function(configJSON) {
|
||||
return console.info(prettyjson.render(configJSON));
|
||||
}).nodeify(done);
|
||||
}
|
||||
};
|
||||
|
||||
exports.write = {
|
||||
signature: 'config write <key> <value>',
|
||||
description: 'write a device configuration',
|
||||
help: 'Use this command to write the config.json file to the mounted filesystem (e.g. SD card) of a provisioned device\n\nExamples:\n\n $ resin config write --type raspberry-pi username johndoe\n $ resin config write --type raspberry-pi --drive /dev/disk2 username johndoe\n $ resin config write --type raspberry-pi files.network/settings "..."',
|
||||
options: [
|
||||
{
|
||||
signature: 'type',
|
||||
description: 'device type (Check available types with `resin devices supported`)',
|
||||
parameter: 'type',
|
||||
alias: 't',
|
||||
required: 'You have to specify a device type'
|
||||
}, {
|
||||
signature: 'drive',
|
||||
description: 'drive',
|
||||
parameter: 'drive',
|
||||
alias: 'd'
|
||||
}
|
||||
],
|
||||
permission: 'user',
|
||||
root: true,
|
||||
action: function(params, options, done) {
|
||||
var Promise, _, config, umountAsync, visuals;
|
||||
Promise = require('bluebird');
|
||||
_ = require('lodash');
|
||||
config = require('resin-config-json');
|
||||
visuals = require('resin-cli-visuals');
|
||||
umountAsync = Promise.promisify(require('umount').umount);
|
||||
return Promise["try"](function() {
|
||||
return options.drive || visuals.drive('Select the device drive');
|
||||
}).tap(umountAsync).then(function(drive) {
|
||||
return config.read(drive, options.type).then(function(configJSON) {
|
||||
console.info("Setting " + params.key + " to " + params.value);
|
||||
_.set(configJSON, params.key, params.value);
|
||||
return configJSON;
|
||||
}).tap(function() {
|
||||
return umountAsync(drive);
|
||||
}).then(function(configJSON) {
|
||||
return config.write(drive, options.type, configJSON);
|
||||
});
|
||||
}).tap(function() {
|
||||
return console.info('Done');
|
||||
}).nodeify(done);
|
||||
}
|
||||
};
|
||||
|
||||
exports.inject = {
|
||||
signature: 'config inject <file>',
|
||||
description: 'inject a device configuration file',
|
||||
help: 'Use this command to inject a config.json file to the mounted filesystem (e.g. SD card) of a provisioned device"\n\nExamples:\n\n $ resin config inject my/config.json --type raspberry-pi\n $ resin config inject my/config.json --type raspberry-pi --drive /dev/disk2',
|
||||
options: [
|
||||
{
|
||||
signature: 'type',
|
||||
description: 'device type (Check available types with `resin devices supported`)',
|
||||
parameter: 'type',
|
||||
alias: 't',
|
||||
required: 'You have to specify a device type'
|
||||
}, {
|
||||
signature: 'drive',
|
||||
description: 'drive',
|
||||
parameter: 'drive',
|
||||
alias: 'd'
|
||||
}
|
||||
],
|
||||
permission: 'user',
|
||||
root: true,
|
||||
action: function(params, options, done) {
|
||||
var Promise, config, readFileAsync, umountAsync, visuals;
|
||||
Promise = require('bluebird');
|
||||
config = require('resin-config-json');
|
||||
visuals = require('resin-cli-visuals');
|
||||
umountAsync = Promise.promisify(require('umount').umount);
|
||||
readFileAsync = Promise.promisify(require('fs').readFile);
|
||||
return Promise["try"](function() {
|
||||
return options.drive || visuals.drive('Select the device drive');
|
||||
}).tap(umountAsync).then(function(drive) {
|
||||
return readFileAsync(params.file, 'utf8').then(JSON.parse).then(function(configJSON) {
|
||||
return config.write(drive, options.type, configJSON);
|
||||
});
|
||||
}).tap(function() {
|
||||
return console.info('Done');
|
||||
}).nodeify(done);
|
||||
}
|
||||
};
|
||||
|
||||
exports.reconfigure = {
|
||||
signature: 'config reconfigure',
|
||||
description: 'reconfigure a provisioned device',
|
||||
help: 'Use this command to reconfigure a provisioned device\n\nExamples:\n\n $ resin config reconfigure --type raspberry-pi\n $ resin config reconfigure --type raspberry-pi --advanced\n $ resin config reconfigure --type raspberry-pi --drive /dev/disk2',
|
||||
options: [
|
||||
{
|
||||
signature: 'type',
|
||||
description: 'device type (Check available types with `resin devices supported`)',
|
||||
parameter: 'type',
|
||||
alias: 't',
|
||||
required: 'You have to specify a device type'
|
||||
}, {
|
||||
signature: 'drive',
|
||||
description: 'drive',
|
||||
parameter: 'drive',
|
||||
alias: 'd'
|
||||
}, {
|
||||
signature: 'advanced',
|
||||
description: 'show advanced commands',
|
||||
boolean: true,
|
||||
alias: 'v'
|
||||
}
|
||||
],
|
||||
permission: 'user',
|
||||
root: true,
|
||||
action: function(params, options, done) {
|
||||
var Promise, capitanoRunAsync, config, umountAsync, visuals;
|
||||
Promise = require('bluebird');
|
||||
config = require('resin-config-json');
|
||||
visuals = require('resin-cli-visuals');
|
||||
capitanoRunAsync = Promise.promisify(require('capitano').run);
|
||||
umountAsync = Promise.promisify(require('umount').umount);
|
||||
return Promise["try"](function() {
|
||||
return options.drive || visuals.drive('Select the device drive');
|
||||
}).tap(umountAsync).then(function(drive) {
|
||||
return config.read(drive, options.type).get('uuid').tap(function() {
|
||||
return umountAsync(drive);
|
||||
}).then(function(uuid) {
|
||||
var configureCommand;
|
||||
configureCommand = "os configure " + drive + " " + uuid;
|
||||
if (options.advanced) {
|
||||
configureCommand += ' --advanced';
|
||||
}
|
||||
return capitanoRunAsync(configureCommand);
|
||||
});
|
||||
}).then(function() {
|
||||
return console.info('Done');
|
||||
}).nodeify(done);
|
||||
}
|
||||
};
|
||||
|
||||
exports.generate = {
|
||||
signature: 'config generate',
|
||||
description: 'generate a config.json file',
|
||||
help: 'Use this command to generate a config.json for a device or application.\n\nThis is interactive by default, but you can do this automatically without interactivity\nby specifying an option for each question on the command line, if you know the questions\nthat will be asked for the relevant device type.\n\nExamples:\n\n $ resin config generate --device 7cf02a6\n $ resin config generate --device 7cf02a6 --device-api-key <existingDeviceKey>\n $ resin config generate --device 7cf02a6 --output config.json\n $ resin config generate --app MyApp\n $ resin config generate --app MyApp --output config.json\n $ resin config generate --app MyApp --network wifi --wifiSsid mySsid --wifiKey abcdefgh --appUpdatePollInterval 1',
|
||||
options: [
|
||||
commandOptions.optionalApplication, commandOptions.optionalDevice, commandOptions.optionalDeviceApiKey, {
|
||||
signature: 'output',
|
||||
description: 'output',
|
||||
parameter: 'output',
|
||||
alias: 'o'
|
||||
}, {
|
||||
signature: 'network',
|
||||
description: 'the network type to use: ethernet or wifi',
|
||||
parameter: 'network'
|
||||
}, {
|
||||
signature: 'wifiSsid',
|
||||
description: 'the wifi ssid to use (used only if --network is set to wifi)',
|
||||
parameter: 'wifiSsid'
|
||||
}, {
|
||||
signature: 'wifiKey',
|
||||
description: 'the wifi key to use (used only if --network is set to wifi)',
|
||||
parameter: 'wifiKey'
|
||||
}, {
|
||||
signature: 'appUpdatePollInterval',
|
||||
description: 'how frequently (in minutes) to poll for application updates',
|
||||
parameter: 'appUpdatePollInterval'
|
||||
}
|
||||
],
|
||||
permission: 'user',
|
||||
action: function(params, options, done) {
|
||||
var Promise, _, deviceConfig, form, generateApplicationConfig, generateDeviceConfig, prettyjson, ref, resin, writeFileAsync;
|
||||
Promise = require('bluebird');
|
||||
writeFileAsync = Promise.promisify(require('fs').writeFile);
|
||||
resin = require('resin-sdk-preconfigured');
|
||||
_ = require('lodash');
|
||||
form = require('resin-cli-form');
|
||||
deviceConfig = require('resin-device-config');
|
||||
prettyjson = require('prettyjson');
|
||||
ref = require('../utils/config'), generateDeviceConfig = ref.generateDeviceConfig, generateApplicationConfig = ref.generateApplicationConfig;
|
||||
if ((options.device == null) && (options.application == null)) {
|
||||
throw new Error('You have to pass either a device or an application.\n\nSee the help page for examples:\n\n $ resin help config generate');
|
||||
}
|
||||
return Promise["try"](function() {
|
||||
if (options.device != null) {
|
||||
return resin.models.device.get(options.device);
|
||||
}
|
||||
return resin.models.application.get(options.application);
|
||||
}).then(function(resource) {
|
||||
return resin.models.device.getManifestBySlug(resource.device_type).get('options').then(function(formOptions) {
|
||||
return form.run(formOptions, {
|
||||
override: options
|
||||
});
|
||||
}).then(function(answers) {
|
||||
if (resource.uuid != null) {
|
||||
return generateDeviceConfig(resource, options.deviceApiKey, answers);
|
||||
} else {
|
||||
return generateApplicationConfig(resource, answers);
|
||||
}
|
||||
});
|
||||
}).then(function(config) {
|
||||
deviceConfig.validate(config);
|
||||
if (options.output != null) {
|
||||
return writeFileAsync(options.output, JSON.stringify(config));
|
||||
}
|
||||
return console.log(prettyjson.render(config));
|
||||
}).nodeify(done);
|
||||
}
|
||||
};
|
@ -1,239 +0,0 @@
|
||||
// Generated by CoffeeScript 1.12.7
|
||||
var Promise, dockerUtils, formatImageName, getBuilderLogPushEndpoint, getBuilderPushEndpoint, getBundleInfo, parseInput, performUpload, showPushProgress, uploadLogs, uploadToPromise;
|
||||
|
||||
Promise = require('bluebird');
|
||||
|
||||
dockerUtils = require('../utils/docker');
|
||||
|
||||
getBuilderPushEndpoint = function(baseUrl, owner, app) {
|
||||
var args, querystring;
|
||||
querystring = require('querystring');
|
||||
args = querystring.stringify({
|
||||
owner: owner,
|
||||
app: app
|
||||
});
|
||||
return "https://builder." + baseUrl + "/v1/push?" + args;
|
||||
};
|
||||
|
||||
getBuilderLogPushEndpoint = function(baseUrl, buildId, owner, app) {
|
||||
var args, querystring;
|
||||
querystring = require('querystring');
|
||||
args = querystring.stringify({
|
||||
owner: owner,
|
||||
app: app,
|
||||
buildId: buildId
|
||||
});
|
||||
return "https://builder." + baseUrl + "/v1/pushLogs?" + args;
|
||||
};
|
||||
|
||||
formatImageName = function(image) {
|
||||
return image.split('/').pop();
|
||||
};
|
||||
|
||||
parseInput = Promise.method(function(params, options) {
|
||||
var appName, image, source;
|
||||
if (params.appName == null) {
|
||||
throw new Error('Need an application to deploy to!');
|
||||
}
|
||||
appName = params.appName;
|
||||
image = void 0;
|
||||
if (params.image != null) {
|
||||
if (options.build || (options.source != null)) {
|
||||
throw new Error('Build and source parameters are not applicable when specifying an image');
|
||||
}
|
||||
options.build = false;
|
||||
image = params.image;
|
||||
} else if (options.build) {
|
||||
source = options.source || '.';
|
||||
} else {
|
||||
throw new Error('Need either an image or a build flag!');
|
||||
}
|
||||
return [appName, options.build, source, image];
|
||||
});
|
||||
|
||||
showPushProgress = function(message) {
|
||||
var progressBar, visuals;
|
||||
visuals = require('resin-cli-visuals');
|
||||
progressBar = new visuals.Progress(message);
|
||||
progressBar.update({
|
||||
percentage: 0
|
||||
});
|
||||
return progressBar;
|
||||
};
|
||||
|
||||
getBundleInfo = function(options) {
|
||||
var helpers;
|
||||
helpers = require('../utils/helpers');
|
||||
return helpers.getAppInfo(options.appName).then(function(app) {
|
||||
return [app.arch, app.device_type];
|
||||
});
|
||||
};
|
||||
|
||||
performUpload = function(imageStream, token, username, url, appName, logger) {
|
||||
var progressBar, progressMessage, progressStream, request, streamWithProgress, uploadRequest, zlib;
|
||||
request = require('request');
|
||||
progressStream = require('progress-stream');
|
||||
zlib = require('zlib');
|
||||
progressMessage = logger.formatMessage('info', 'Deploying').slice(0, -1);
|
||||
progressBar = showPushProgress(progressMessage);
|
||||
streamWithProgress = imageStream.pipe(progressStream({
|
||||
time: 500,
|
||||
length: imageStream.length
|
||||
}, function(arg) {
|
||||
var eta, percentage;
|
||||
percentage = arg.percentage, eta = arg.eta;
|
||||
return progressBar.update({
|
||||
percentage: Math.min(percentage, 100),
|
||||
eta: eta
|
||||
});
|
||||
}));
|
||||
uploadRequest = request.post({
|
||||
url: getBuilderPushEndpoint(url, username, appName),
|
||||
headers: {
|
||||
'Content-Encoding': 'gzip'
|
||||
},
|
||||
auth: {
|
||||
bearer: token
|
||||
},
|
||||
body: streamWithProgress.pipe(zlib.createGzip({
|
||||
level: 6
|
||||
}))
|
||||
});
|
||||
return uploadToPromise(uploadRequest, logger);
|
||||
};
|
||||
|
||||
uploadLogs = function(logs, token, url, buildId, username, appName) {
|
||||
var request;
|
||||
request = require('request');
|
||||
return request.post({
|
||||
json: true,
|
||||
url: getBuilderLogPushEndpoint(url, buildId, username, appName),
|
||||
auth: {
|
||||
bearer: token
|
||||
},
|
||||
body: Buffer.from(logs)
|
||||
});
|
||||
};
|
||||
|
||||
uploadToPromise = function(uploadRequest, logger) {
|
||||
return new Promise(function(resolve, reject) {
|
||||
var handleMessage;
|
||||
handleMessage = function(data) {
|
||||
var e, obj;
|
||||
data = data.toString();
|
||||
logger.logDebug("Received data: " + data);
|
||||
try {
|
||||
obj = JSON.parse(data);
|
||||
} catch (error) {
|
||||
e = error;
|
||||
logger.logError('Error parsing reply from remote side');
|
||||
reject(e);
|
||||
return;
|
||||
}
|
||||
if (obj.type != null) {
|
||||
switch (obj.type) {
|
||||
case 'error':
|
||||
return reject(new Error("Remote error: " + obj.error));
|
||||
case 'success':
|
||||
return resolve(obj);
|
||||
case 'status':
|
||||
return logger.logInfo("Remote: " + obj.message);
|
||||
default:
|
||||
return reject(new Error("Received unexpected reply from remote: " + data));
|
||||
}
|
||||
} else {
|
||||
return reject(new Error("Received unexpected reply from remote: " + data));
|
||||
}
|
||||
};
|
||||
return uploadRequest.on('error', reject).on('data', handleMessage);
|
||||
});
|
||||
};
|
||||
|
||||
module.exports = {
|
||||
signature: 'deploy <appName> [image]',
|
||||
description: 'Deploy an image to a resin.io application',
|
||||
help: 'Use this command to deploy an image to an application, optionally building it first.\n\nUsage: `deploy <appName> ([image] | --build [--source build-dir])`\n\nTo deploy to an app on which you\'re a collaborator, use\n`resin deploy <appOwnerUsername>/<appName>`.\n\nNote: If building with this command, all options supported by `resin build`\nare also supported with this command.\n\nExamples:\n $ resin deploy myApp --build --source myBuildDir/\n $ resin deploy myApp myApp/myImage',
|
||||
permission: 'user',
|
||||
options: dockerUtils.appendOptions([
|
||||
{
|
||||
signature: 'build',
|
||||
boolean: true,
|
||||
description: 'Build image then deploy',
|
||||
alias: 'b'
|
||||
}, {
|
||||
signature: 'source',
|
||||
parameter: 'source',
|
||||
description: 'The source directory to use when building the image',
|
||||
alias: 's'
|
||||
}, {
|
||||
signature: 'nologupload',
|
||||
description: "Don't upload build logs to the dashboard with image (if building)",
|
||||
boolean: true
|
||||
}
|
||||
]),
|
||||
action: function(params, options, done) {
|
||||
var Logger, _, logger, logs, resin, tmp, tmpNameAsync, upload;
|
||||
_ = require('lodash');
|
||||
tmp = require('tmp');
|
||||
tmpNameAsync = Promise.promisify(tmp.tmpName);
|
||||
resin = require('resin-sdk-preconfigured');
|
||||
Logger = require('../utils/logger');
|
||||
logger = new Logger();
|
||||
tmp.setGracefulCleanup();
|
||||
logs = '';
|
||||
upload = function(token, username, url) {
|
||||
return dockerUtils.getDocker(options).then(function(docker) {
|
||||
return parseInput(params, options).then(function(arg) {
|
||||
var appName, build, imageName, source;
|
||||
appName = arg[0], build = arg[1], source = arg[2], imageName = arg[3];
|
||||
return tmpNameAsync().then(function(bufferFile) {
|
||||
options = _.assign({}, options, {
|
||||
appName: appName
|
||||
});
|
||||
params = _.assign({}, params, {
|
||||
source: source
|
||||
});
|
||||
return Promise["try"](function() {
|
||||
if (build) {
|
||||
return dockerUtils.runBuild(params, options, getBundleInfo, logger);
|
||||
} else {
|
||||
return {
|
||||
image: imageName,
|
||||
log: ''
|
||||
};
|
||||
}
|
||||
}).then(function(arg1) {
|
||||
var buildLogs, imageName;
|
||||
imageName = arg1.image, buildLogs = arg1.log;
|
||||
logger.logInfo('Initializing deploy...');
|
||||
logs = buildLogs;
|
||||
return Promise.all([dockerUtils.bufferImage(docker, imageName, bufferFile), token, username, url, params.appName, logger]).spread(performUpload);
|
||||
})["finally"](function() {
|
||||
return Promise["try"](function() {
|
||||
return require('mz/fs').unlink(bufferFile);
|
||||
})["catch"](_.noop);
|
||||
});
|
||||
});
|
||||
}).tap(function(arg) {
|
||||
var buildId, imageName;
|
||||
imageName = arg.image, buildId = arg.buildId;
|
||||
logger.logSuccess("Successfully deployed image: " + (formatImageName(imageName)));
|
||||
return buildId;
|
||||
}).then(function(arg) {
|
||||
var buildId, imageName;
|
||||
imageName = arg.image, buildId = arg.buildId;
|
||||
if (logs === '' || (options.nologupload != null)) {
|
||||
return '';
|
||||
}
|
||||
logger.logInfo('Uploading logs to dashboard...');
|
||||
return Promise.join(logs, token, url, buildId, username, params.appName, uploadLogs)["return"]('Successfully uploaded logs');
|
||||
}).then(function(msg) {
|
||||
if (msg !== '') {
|
||||
return logger.logSuccess(msg);
|
||||
}
|
||||
}).asCallback(done);
|
||||
});
|
||||
};
|
||||
return Promise.join(resin.auth.getToken(), resin.auth.whoami(), resin.settings.get('resinUrl'), upload);
|
||||
}
|
||||
};
|
@ -1,336 +0,0 @@
|
||||
// Generated by CoffeeScript 1.12.7
|
||||
|
||||
/*
|
||||
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 _, commandOptions;
|
||||
|
||||
commandOptions = require('./command-options');
|
||||
|
||||
_ = require('lodash');
|
||||
|
||||
exports.list = {
|
||||
signature: 'devices',
|
||||
description: 'list all devices',
|
||||
help: 'Use this command to list all devices that belong to you.\n\nYou can filter the devices by application by using the `--application` option.\n\nExamples:\n\n $ resin devices\n $ resin devices --application MyApp\n $ resin devices --app MyApp\n $ resin devices -a MyApp',
|
||||
options: [commandOptions.optionalApplication],
|
||||
permission: 'user',
|
||||
primary: true,
|
||||
action: function(params, options, done) {
|
||||
var Promise, resin, visuals;
|
||||
Promise = require('bluebird');
|
||||
resin = require('resin-sdk-preconfigured');
|
||||
visuals = require('resin-cli-visuals');
|
||||
return Promise["try"](function() {
|
||||
if (options.application != null) {
|
||||
return resin.models.device.getAllByApplication(options.application);
|
||||
}
|
||||
return resin.models.device.getAll();
|
||||
}).tap(function(devices) {
|
||||
devices = _.map(devices, function(device) {
|
||||
device.uuid = device.uuid.slice(0, 7);
|
||||
return device;
|
||||
});
|
||||
return console.log(visuals.table.horizontal(devices, ['id', 'uuid', 'name', 'device_type', 'application_name', 'status', 'is_online', 'supervisor_version', 'os_version', 'dashboard_url']));
|
||||
}).nodeify(done);
|
||||
}
|
||||
};
|
||||
|
||||
exports.info = {
|
||||
signature: 'device <uuid>',
|
||||
description: 'list a single device',
|
||||
help: 'Use this command to show information about a single device.\n\nExamples:\n\n $ resin device 7cf02a6',
|
||||
permission: 'user',
|
||||
primary: true,
|
||||
action: function(params, options, done) {
|
||||
var resin, visuals;
|
||||
resin = require('resin-sdk-preconfigured');
|
||||
visuals = require('resin-cli-visuals');
|
||||
return resin.models.device.get(params.uuid).then(function(device) {
|
||||
return resin.models.device.getStatus(device).then(function(status) {
|
||||
device.status = status;
|
||||
return console.log(visuals.table.vertical(device, ["$" + device.name + "$", 'id', 'device_type', 'status', 'is_online', 'ip_address', 'application_name', 'last_seen', 'uuid', 'commit', 'supervisor_version', 'is_web_accessible', 'note', 'os_version', 'dashboard_url']));
|
||||
});
|
||||
}).nodeify(done);
|
||||
}
|
||||
};
|
||||
|
||||
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',
|
||||
action: function(params, options, done) {
|
||||
var resin, visuals;
|
||||
resin = require('resin-sdk-preconfigured');
|
||||
visuals = require('resin-cli-visuals');
|
||||
return resin.models.config.getDeviceTypes().then(function(deviceTypes) {
|
||||
return console.log(visuals.table.horizontal(deviceTypes, ['slug', 'name']));
|
||||
}).nodeify(done);
|
||||
}
|
||||
};
|
||||
|
||||
exports.register = {
|
||||
signature: 'device register <application>',
|
||||
description: 'register a device',
|
||||
help: 'Use this command to register a device to an application.\n\nNote that device api keys are only supported on ResinOS 2.0.3+\n\nExamples:\n\n $ resin device register MyApp\n $ resin device register MyApp --uuid <uuid>\n $ resin device register MyApp --uuid <uuid> --device-api-key <existingDeviceKey>',
|
||||
permission: 'user',
|
||||
options: [
|
||||
{
|
||||
signature: 'uuid',
|
||||
description: 'custom uuid',
|
||||
parameter: 'uuid',
|
||||
alias: 'u'
|
||||
}, commandOptions.optionalDeviceApiKey
|
||||
],
|
||||
action: function(params, options, done) {
|
||||
var Promise, ref, ref1, resin;
|
||||
Promise = require('bluebird');
|
||||
resin = require('resin-sdk-preconfigured');
|
||||
return Promise.join(resin.models.application.get(params.application), (ref = options.uuid) != null ? ref : resin.models.device.generateUniqueKey(), (ref1 = options.deviceApiKey) != null ? ref1 : resin.models.device.generateUniqueKey(), function(application, uuid, deviceApiKey) {
|
||||
console.info("Registering to " + application.app_name + ": " + uuid);
|
||||
if (options.deviceApiKey == null) {
|
||||
console.info("Using generated device api key: " + deviceApiKey);
|
||||
} else {
|
||||
console.info('Using provided device api key');
|
||||
}
|
||||
return resin.models.device.register(application.id, uuid, deviceApiKey);
|
||||
}).get('uuid').nodeify(done);
|
||||
}
|
||||
};
|
||||
|
||||
exports.remove = {
|
||||
signature: 'device rm <uuid>',
|
||||
description: 'remove a device',
|
||||
help: 'Use this command to remove a device from resin.io.\n\nNotice this command asks for confirmation interactively.\nYou can avoid this by passing the `--yes` boolean option.\n\nExamples:\n\n $ resin device rm 7cf02a6\n $ resin device rm 7cf02a6 --yes',
|
||||
options: [commandOptions.yes],
|
||||
permission: 'user',
|
||||
action: function(params, options, done) {
|
||||
var patterns, resin;
|
||||
resin = require('resin-sdk-preconfigured');
|
||||
patterns = require('../utils/patterns');
|
||||
return patterns.confirm(options.yes, 'Are you sure you want to delete the device?').then(function() {
|
||||
return resin.models.device.remove(params.uuid);
|
||||
}).nodeify(done);
|
||||
}
|
||||
};
|
||||
|
||||
exports.identify = {
|
||||
signature: 'device identify <uuid>',
|
||||
description: 'identify a device with a UUID',
|
||||
help: 'Use this command to identify a device.\n\nIn the Raspberry Pi, the ACT led is blinked several times.\n\nExamples:\n\n $ resin device identify 23c73a1',
|
||||
permission: 'user',
|
||||
action: function(params, options, done) {
|
||||
var resin;
|
||||
resin = require('resin-sdk-preconfigured');
|
||||
return resin.models.device.identify(params.uuid).nodeify(done);
|
||||
}
|
||||
};
|
||||
|
||||
exports.reboot = {
|
||||
signature: 'device reboot <uuid>',
|
||||
description: 'restart a device',
|
||||
help: 'Use this command to remotely reboot a device\n\nExamples:\n\n $ resin device reboot 23c73a1',
|
||||
options: [commandOptions.forceUpdateLock],
|
||||
permission: 'user',
|
||||
action: function(params, options, done) {
|
||||
var resin;
|
||||
resin = require('resin-sdk-preconfigured');
|
||||
return resin.models.device.reboot(params.uuid, options).nodeify(done);
|
||||
}
|
||||
};
|
||||
|
||||
exports.shutdown = {
|
||||
signature: 'device shutdown <uuid>',
|
||||
description: 'shutdown a device',
|
||||
help: 'Use this command to remotely shutdown a device\n\nExamples:\n\n $ resin device shutdown 23c73a1',
|
||||
options: [commandOptions.forceUpdateLock],
|
||||
permission: 'user',
|
||||
action: function(params, options, done) {
|
||||
var resin;
|
||||
resin = require('resin-sdk-preconfigured');
|
||||
return resin.models.device.shutdown(params.uuid, options).nodeify(done);
|
||||
}
|
||||
};
|
||||
|
||||
exports.enableDeviceUrl = {
|
||||
signature: 'device public-url enable <uuid>',
|
||||
description: 'enable public URL for a device',
|
||||
help: 'Use this command to enable public URL for a device\n\nExamples:\n\n $ resin device public-url enable 23c73a1',
|
||||
permission: 'user',
|
||||
action: function(params, options, done) {
|
||||
var resin;
|
||||
resin = require('resin-sdk-preconfigured');
|
||||
return resin.models.device.enableDeviceUrl(params.uuid).nodeify(done);
|
||||
}
|
||||
};
|
||||
|
||||
exports.disableDeviceUrl = {
|
||||
signature: 'device public-url disable <uuid>',
|
||||
description: 'disable public URL for a device',
|
||||
help: 'Use this command to disable public URL for a device\n\nExamples:\n\n $ resin device public-url disable 23c73a1',
|
||||
permission: 'user',
|
||||
action: function(params, options, done) {
|
||||
var resin;
|
||||
resin = require('resin-sdk-preconfigured');
|
||||
return resin.models.device.disableDeviceUrl(params.uuid).nodeify(done);
|
||||
}
|
||||
};
|
||||
|
||||
exports.getDeviceUrl = {
|
||||
signature: 'device public-url <uuid>',
|
||||
description: 'gets the public URL of a device',
|
||||
help: 'Use this command to get the public URL of a device\n\nExamples:\n\n $ resin device public-url 23c73a1',
|
||||
permission: 'user',
|
||||
action: function(params, options, done) {
|
||||
var resin;
|
||||
resin = require('resin-sdk-preconfigured');
|
||||
return resin.models.device.getDeviceUrl(params.uuid).then(function(url) {
|
||||
return console.log(url);
|
||||
}).nodeify(done);
|
||||
}
|
||||
};
|
||||
|
||||
exports.hasDeviceUrl = {
|
||||
signature: 'device public-url status <uuid>',
|
||||
description: 'Returns true if public URL is enabled for a device',
|
||||
help: 'Use this command to determine if public URL is enabled for a device\n\nExamples:\n\n $ resin device public-url status 23c73a1',
|
||||
permission: 'user',
|
||||
action: function(params, options, done) {
|
||||
var resin;
|
||||
resin = require('resin-sdk-preconfigured');
|
||||
return resin.models.device.hasDeviceUrl(params.uuid).then(function(hasDeviceUrl) {
|
||||
return console.log(hasDeviceUrl);
|
||||
}).nodeify(done);
|
||||
}
|
||||
};
|
||||
|
||||
exports.rename = {
|
||||
signature: 'device rename <uuid> [newName]',
|
||||
description: 'rename a resin device',
|
||||
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;
|
||||
Promise = require('bluebird');
|
||||
resin = require('resin-sdk-preconfigured');
|
||||
form = require('resin-cli-form');
|
||||
return Promise["try"](function() {
|
||||
if (!_.isEmpty(params.newName)) {
|
||||
return params.newName;
|
||||
}
|
||||
return form.ask({
|
||||
message: 'How do you want to name this device?',
|
||||
type: 'input'
|
||||
});
|
||||
}).then(_.partial(resin.models.device.rename, params.uuid)).nodeify(done);
|
||||
}
|
||||
};
|
||||
|
||||
exports.move = {
|
||||
signature: 'device move <uuid>',
|
||||
description: 'move a device to another application',
|
||||
help: 'Use this command to move a device to another application you own.\n\nIf you omit the application, you\'ll get asked for it interactively.\n\nExamples:\n\n $ resin device move 7cf02a6\n $ resin device move 7cf02a6 --application MyNewApp',
|
||||
permission: 'user',
|
||||
options: [commandOptions.optionalApplication],
|
||||
action: function(params, options, done) {
|
||||
var patterns, resin;
|
||||
resin = require('resin-sdk-preconfigured');
|
||||
patterns = require('../utils/patterns');
|
||||
return resin.models.device.get(params.uuid).then(function(device) {
|
||||
return options.application || patterns.selectApplication(function(application) {
|
||||
return _.every([application.device_type === device.device_type, device.application_name !== application.app_name]);
|
||||
});
|
||||
}).tap(function(application) {
|
||||
return resin.models.device.move(params.uuid, application);
|
||||
}).then(function(application) {
|
||||
return console.info(params.uuid + " was moved to " + application);
|
||||
}).nodeify(done);
|
||||
}
|
||||
};
|
||||
|
||||
exports.init = {
|
||||
signature: 'device init',
|
||||
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, 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',
|
||||
action: function(params, options, done) {
|
||||
var Promise, capitanoRunAsync, helpers, patterns, resin, rimraf, tmp, tmpNameAsync;
|
||||
Promise = require('bluebird');
|
||||
capitanoRunAsync = Promise.promisify(require('capitano').run);
|
||||
rimraf = Promise.promisify(require('rimraf'));
|
||||
tmp = require('tmp');
|
||||
tmpNameAsync = Promise.promisify(tmp.tmpName);
|
||||
tmp.setGracefulCleanup();
|
||||
resin = require('resin-sdk-preconfigured');
|
||||
helpers = require('../utils/helpers');
|
||||
patterns = require('../utils/patterns');
|
||||
return Promise["try"](function() {
|
||||
if (options.application != null) {
|
||||
return options.application;
|
||||
}
|
||||
return patterns.selectApplication();
|
||||
}).then(resin.models.application.get).then(function(application) {
|
||||
var download;
|
||||
download = function() {
|
||||
return tmpNameAsync().then(function(tempPath) {
|
||||
var osVersion;
|
||||
osVersion = options['os-version'] || 'default';
|
||||
return capitanoRunAsync("os download " + application.device_type + " --output '" + tempPath + "' --version " + osVersion);
|
||||
}).disposer(function(tempPath) {
|
||||
return rimraf(tempPath);
|
||||
});
|
||||
};
|
||||
return Promise.using(download(), function(tempPath) {
|
||||
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.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() {
|
||||
throw error;
|
||||
});
|
||||
});
|
||||
});
|
||||
}).then(function(device) {
|
||||
console.log('Done');
|
||||
return device.uuid;
|
||||
});
|
||||
}).nodeify(done);
|
||||
}
|
||||
};
|
@ -1,131 +0,0 @@
|
||||
// Generated by CoffeeScript 1.12.7
|
||||
|
||||
/*
|
||||
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 commandOptions;
|
||||
|
||||
commandOptions = require('./command-options');
|
||||
|
||||
exports.list = {
|
||||
signature: 'envs',
|
||||
description: 'list all environment variables',
|
||||
help: 'Use this command to list all environment variables for\na particular application or device.\n\nThis command lists all custom environment variables.\nIf you want to see all environment variables, including private\nones used by resin, use the verbose option.\n\nExample:\n\n $ resin envs --application MyApp\n $ resin envs --application MyApp --verbose\n $ resin envs --device 7cf02a6',
|
||||
options: [
|
||||
commandOptions.optionalApplication, commandOptions.optionalDevice, {
|
||||
signature: 'verbose',
|
||||
description: 'show private environment variables',
|
||||
boolean: true,
|
||||
alias: 'v'
|
||||
}
|
||||
],
|
||||
permission: 'user',
|
||||
action: function(params, options, done) {
|
||||
var Promise, _, resin, visuals;
|
||||
Promise = require('bluebird');
|
||||
_ = require('lodash');
|
||||
resin = require('resin-sdk-preconfigured');
|
||||
visuals = require('resin-cli-visuals');
|
||||
return Promise["try"](function() {
|
||||
if (options.application != null) {
|
||||
return resin.models.environmentVariables.getAllByApplication(options.application);
|
||||
} else if (options.device != null) {
|
||||
return resin.models.environmentVariables.device.getAll(options.device);
|
||||
} else {
|
||||
throw new Error('You must specify an application or device');
|
||||
}
|
||||
}).tap(function(environmentVariables) {
|
||||
var isSystemVariable;
|
||||
if (_.isEmpty(environmentVariables)) {
|
||||
throw new Error('No environment variables found');
|
||||
}
|
||||
if (!options.verbose) {
|
||||
isSystemVariable = resin.models.environmentVariables.isSystemVariable;
|
||||
environmentVariables = _.reject(environmentVariables, isSystemVariable);
|
||||
}
|
||||
return console.log(visuals.table.horizontal(environmentVariables, ['id', 'name', 'value']));
|
||||
}).nodeify(done);
|
||||
}
|
||||
};
|
||||
|
||||
exports.remove = {
|
||||
signature: 'env rm <id>',
|
||||
description: 'remove an environment variable',
|
||||
help: 'Use this command to remove an environment variable from an application.\n\nDon\'t remove resin specific variables, as things might not work as expected.\n\nNotice this command asks for confirmation interactively.\nYou can avoid this by passing the `--yes` boolean option.\n\nIf you want to eliminate a device environment variable, pass the `--device` boolean option.\n\nExamples:\n\n $ resin env rm 215\n $ resin env rm 215 --yes\n $ resin env rm 215 --device',
|
||||
options: [commandOptions.yes, commandOptions.booleanDevice],
|
||||
permission: 'user',
|
||||
action: function(params, options, done) {
|
||||
var patterns, resin;
|
||||
resin = require('resin-sdk-preconfigured');
|
||||
patterns = require('../utils/patterns');
|
||||
return patterns.confirm(options.yes, 'Are you sure you want to delete the environment variable?').then(function() {
|
||||
if (options.device) {
|
||||
return resin.models.environmentVariables.device.remove(params.id);
|
||||
} else {
|
||||
return resin.models.environmentVariables.remove(params.id);
|
||||
}
|
||||
}).nodeify(done);
|
||||
}
|
||||
};
|
||||
|
||||
exports.add = {
|
||||
signature: 'env add <key> [value]',
|
||||
description: 'add an environment variable',
|
||||
help: 'Use this command to add an enviroment variable to an application.\n\nIf value is omitted, the tool will attempt to use the variable\'s value\nas defined in your host machine.\n\nUse the `--device` option if you want to assign the environment variable\nto a specific device.\n\nIf the value is grabbed from the environment, a warning message will be printed.\nUse `--quiet` to remove it.\n\nExamples:\n\n $ resin env add EDITOR vim --application MyApp\n $ resin env add TERM --application MyApp\n $ resin env add EDITOR vim --device 7cf02a6',
|
||||
options: [commandOptions.optionalApplication, commandOptions.optionalDevice],
|
||||
permission: 'user',
|
||||
action: function(params, options, done) {
|
||||
var Promise, resin;
|
||||
Promise = require('bluebird');
|
||||
resin = require('resin-sdk-preconfigured');
|
||||
return Promise["try"](function() {
|
||||
if (params.value == null) {
|
||||
params.value = process.env[params.key];
|
||||
if (params.value == null) {
|
||||
throw new Error("Environment value not found for key: " + params.key);
|
||||
} else {
|
||||
console.info("Warning: using " + params.key + "=" + params.value + " from host environment");
|
||||
}
|
||||
}
|
||||
if (options.application != null) {
|
||||
return resin.models.environmentVariables.create(options.application, params.key, params.value);
|
||||
} else if (options.device != null) {
|
||||
return resin.models.environmentVariables.device.create(options.device, params.key, params.value);
|
||||
} else {
|
||||
throw new Error('You must specify an application or device');
|
||||
}
|
||||
}).nodeify(done);
|
||||
}
|
||||
};
|
||||
|
||||
exports.rename = {
|
||||
signature: 'env rename <id> <value>',
|
||||
description: 'rename an environment variable',
|
||||
help: 'Use this command to rename an enviroment variable from an application.\n\nPass the `--device` boolean option if you want to rename a device environment variable.\n\nExamples:\n\n $ resin env rename 376 emacs\n $ resin env rename 376 emacs --device',
|
||||
permission: 'user',
|
||||
options: [commandOptions.booleanDevice],
|
||||
action: function(params, options, done) {
|
||||
var Promise, resin;
|
||||
Promise = require('bluebird');
|
||||
resin = require('resin-sdk-preconfigured');
|
||||
return Promise["try"](function() {
|
||||
if (options.device) {
|
||||
return resin.models.environmentVariables.device.update(params.id, params.value);
|
||||
} else {
|
||||
return resin.models.environmentVariables.update(params.id, params.value);
|
||||
}
|
||||
}).nodeify(done);
|
||||
}
|
||||
};
|
@ -1,133 +0,0 @@
|
||||
// Generated by CoffeeScript 1.12.7
|
||||
|
||||
/*
|
||||
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 _, capitano, columnify, command, general, indent, messages, parse, print;
|
||||
|
||||
_ = require('lodash');
|
||||
|
||||
_.str = require('underscore.string');
|
||||
|
||||
capitano = require('capitano');
|
||||
|
||||
columnify = require('columnify');
|
||||
|
||||
messages = require('../utils/messages');
|
||||
|
||||
parse = function(object) {
|
||||
return _.fromPairs(_.map(object, function(item) {
|
||||
var signature;
|
||||
if (item.alias != null) {
|
||||
signature = item.toString();
|
||||
} else {
|
||||
signature = item.signature.toString();
|
||||
}
|
||||
return [signature, item.description];
|
||||
}));
|
||||
};
|
||||
|
||||
indent = function(text) {
|
||||
text = _.map(_.str.lines(text), function(line) {
|
||||
return ' ' + line;
|
||||
});
|
||||
return text.join('\n');
|
||||
};
|
||||
|
||||
print = function(data) {
|
||||
return console.log(indent(columnify(data, {
|
||||
showHeaders: false,
|
||||
minWidth: 35
|
||||
})));
|
||||
};
|
||||
|
||||
general = function(params, options, done) {
|
||||
var commands, groupedCommands;
|
||||
console.log('Usage: resin [COMMAND] [OPTIONS]\n');
|
||||
console.log(messages.reachingOut);
|
||||
console.log('\nPrimary commands:\n');
|
||||
commands = _.reject(capitano.state.commands, function(command) {
|
||||
return command.hidden || command.isWildcard();
|
||||
});
|
||||
groupedCommands = _.groupBy(commands, function(command) {
|
||||
if (command.plugin) {
|
||||
return 'plugins';
|
||||
}
|
||||
if (command.primary) {
|
||||
return 'primary';
|
||||
}
|
||||
return 'secondary';
|
||||
});
|
||||
print(parse(groupedCommands.primary));
|
||||
if (options.verbose) {
|
||||
if (!_.isEmpty(groupedCommands.plugins)) {
|
||||
console.log('\nInstalled plugins:\n');
|
||||
print(parse(groupedCommands.plugins));
|
||||
}
|
||||
console.log('\nAdditional commands:\n');
|
||||
print(parse(groupedCommands.secondary));
|
||||
} else {
|
||||
console.log('\nRun `resin help --verbose` to list additional commands');
|
||||
}
|
||||
if (!_.isEmpty(capitano.state.globalOptions)) {
|
||||
console.log('\nGlobal Options:\n');
|
||||
print(parse(capitano.state.globalOptions));
|
||||
}
|
||||
return done();
|
||||
};
|
||||
|
||||
command = function(params, options, done) {
|
||||
return capitano.state.getMatchCommand(params.command, function(error, command) {
|
||||
if (error != null) {
|
||||
return done(error);
|
||||
}
|
||||
if ((command == null) || command.isWildcard()) {
|
||||
return done(new Error("Command not found: " + params.command));
|
||||
}
|
||||
console.log("Usage: " + command.signature);
|
||||
if (command.help != null) {
|
||||
console.log("\n" + command.help);
|
||||
} else if (command.description != null) {
|
||||
console.log("\n" + (_.str.humanize(command.description)));
|
||||
}
|
||||
if (!_.isEmpty(command.options)) {
|
||||
console.log('\nOptions:\n');
|
||||
print(parse(command.options));
|
||||
}
|
||||
return done();
|
||||
});
|
||||
};
|
||||
|
||||
exports.help = {
|
||||
signature: 'help [command...]',
|
||||
description: 'show help',
|
||||
help: 'Get detailed help for an specific command.\n\nExamples:\n\n $ resin help apps\n $ resin help os download',
|
||||
primary: true,
|
||||
options: [
|
||||
{
|
||||
signature: 'verbose',
|
||||
description: 'show additional commands',
|
||||
boolean: true,
|
||||
alias: 'v'
|
||||
}
|
||||
],
|
||||
action: function(params, options, done) {
|
||||
if (params.command != null) {
|
||||
return command(params, options, done);
|
||||
} else {
|
||||
return general(params, options, done);
|
||||
}
|
||||
}
|
||||
};
|
@ -1,40 +0,0 @@
|
||||
// Generated by CoffeeScript 1.12.7
|
||||
|
||||
/*
|
||||
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.
|
||||
*/
|
||||
module.exports = {
|
||||
wizard: require('./wizard'),
|
||||
app: require('./app'),
|
||||
info: require('./info'),
|
||||
auth: require('./auth'),
|
||||
device: require('./device'),
|
||||
env: require('./environment-variables'),
|
||||
keys: require('./keys'),
|
||||
logs: require('./logs'),
|
||||
local: require('./local'),
|
||||
notes: require('./notes'),
|
||||
help: require('./help'),
|
||||
os: require('./os'),
|
||||
settings: require('./settings'),
|
||||
config: require('./config'),
|
||||
sync: require('./sync'),
|
||||
ssh: require('./ssh'),
|
||||
internal: require('./internal'),
|
||||
build: require('./build'),
|
||||
deploy: require('./deploy'),
|
||||
util: require('./util'),
|
||||
preload: require('./preload')
|
||||
};
|
@ -1,28 +0,0 @@
|
||||
// Generated by CoffeeScript 1.12.7
|
||||
|
||||
/*
|
||||
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.
|
||||
*/
|
||||
exports.version = {
|
||||
signature: 'version',
|
||||
description: 'output the version number',
|
||||
help: 'Display the Resin CLI version.',
|
||||
action: function(params, options, done) {
|
||||
var packageJSON;
|
||||
packageJSON = require('../../package.json');
|
||||
console.log(packageJSON.version);
|
||||
return done();
|
||||
}
|
||||
};
|
@ -1,35 +0,0 @@
|
||||
// Generated by CoffeeScript 1.12.7
|
||||
|
||||
/*
|
||||
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.
|
||||
*/
|
||||
exports.osInit = {
|
||||
signature: 'internal osinit <image> <type> <config>',
|
||||
description: 'do actual init of the device with the preconfigured os image',
|
||||
help: 'Don\'t use this command directly! Use `resin os initialize <image>` instead.',
|
||||
hidden: true,
|
||||
root: true,
|
||||
action: function(params, options, done) {
|
||||
var Promise, helpers, init;
|
||||
Promise = require('bluebird');
|
||||
init = require('resin-device-init');
|
||||
helpers = require('../utils/helpers');
|
||||
return Promise["try"](function() {
|
||||
var config;
|
||||
config = JSON.parse(params.config);
|
||||
return init.initialize(params.image, params.type, config);
|
||||
}).then(helpers.osProgressHandler).nodeify(done);
|
||||
}
|
||||
};
|
@ -1,94 +0,0 @@
|
||||
// Generated by CoffeeScript 1.12.7
|
||||
|
||||
/*
|
||||
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 commandOptions;
|
||||
|
||||
commandOptions = require('./command-options');
|
||||
|
||||
exports.list = {
|
||||
signature: 'keys',
|
||||
description: 'list all ssh keys',
|
||||
help: 'Use this command to list all your SSH keys.\n\nExamples:\n\n $ resin keys',
|
||||
permission: 'user',
|
||||
action: function(params, options, done) {
|
||||
var resin, visuals;
|
||||
resin = require('resin-sdk-preconfigured');
|
||||
visuals = require('resin-cli-visuals');
|
||||
return resin.models.key.getAll().then(function(keys) {
|
||||
return console.log(visuals.table.horizontal(keys, ['id', 'title']));
|
||||
}).nodeify(done);
|
||||
}
|
||||
};
|
||||
|
||||
exports.info = {
|
||||
signature: 'key <id>',
|
||||
description: 'list a single ssh key',
|
||||
help: 'Use this command to show information about a single SSH key.\n\nExamples:\n\n $ resin key 17',
|
||||
permission: 'user',
|
||||
action: function(params, options, done) {
|
||||
var resin, visuals;
|
||||
resin = require('resin-sdk-preconfigured');
|
||||
visuals = require('resin-cli-visuals');
|
||||
return resin.models.key.get(params.id).then(function(key) {
|
||||
console.log(visuals.table.vertical(key, ['id', 'title']));
|
||||
return console.log('\n' + key.public_key);
|
||||
}).nodeify(done);
|
||||
}
|
||||
};
|
||||
|
||||
exports.remove = {
|
||||
signature: 'key rm <id>',
|
||||
description: 'remove a ssh key',
|
||||
help: 'Use this command to remove a SSH key from resin.io.\n\nNotice this command asks for confirmation interactively.\nYou can avoid this by passing the `--yes` boolean option.\n\nExamples:\n\n $ resin key rm 17\n $ resin key rm 17 --yes',
|
||||
options: [commandOptions.yes],
|
||||
permission: 'user',
|
||||
action: function(params, options, done) {
|
||||
var patterns, resin;
|
||||
resin = require('resin-sdk-preconfigured');
|
||||
patterns = require('../utils/patterns');
|
||||
return patterns.confirm(options.yes, 'Are you sure you want to delete the key?').then(function() {
|
||||
return resin.models.key.remove(params.id);
|
||||
}).nodeify(done);
|
||||
}
|
||||
};
|
||||
|
||||
exports.add = {
|
||||
signature: 'key add <name> [path]',
|
||||
description: 'add a SSH key to resin.io',
|
||||
help: 'Use this command to associate a new SSH key with your account.\n\nIf `path` is omitted, the command will attempt\nto read the SSH key from stdin.\n\nExamples:\n\n $ resin key add Main ~/.ssh/id_rsa.pub\n $ cat ~/.ssh/id_rsa.pub | resin key add Main',
|
||||
permission: 'user',
|
||||
action: function(params, options, done) {
|
||||
var Promise, _, capitano, readFileAsync, resin;
|
||||
_ = require('lodash');
|
||||
Promise = require('bluebird');
|
||||
readFileAsync = Promise.promisify(require('fs').readFile);
|
||||
capitano = require('capitano');
|
||||
resin = require('resin-sdk-preconfigured');
|
||||
return Promise["try"](function() {
|
||||
if (params.path != null) {
|
||||
return readFileAsync(params.path, {
|
||||
encoding: 'utf8'
|
||||
});
|
||||
}
|
||||
return Promise.fromNode(function(callback) {
|
||||
return capitano.utils.getStdin(function(data) {
|
||||
return callback(null, data);
|
||||
});
|
||||
});
|
||||
}).then(_.partial(resin.models.key.create, params.name)).nodeify(done);
|
||||
}
|
||||
};
|
@ -1,97 +0,0 @@
|
||||
// Generated by CoffeeScript 1.12.7
|
||||
var Docker, Promise, _, chalk, dockerPort, dockerTimeout, filterOutSupervisorContainer, form;
|
||||
|
||||
Promise = require('bluebird');
|
||||
|
||||
_ = require('lodash');
|
||||
|
||||
Docker = require('docker-toolbelt');
|
||||
|
||||
form = require('resin-cli-form');
|
||||
|
||||
chalk = require('chalk');
|
||||
|
||||
exports.dockerPort = dockerPort = 2375;
|
||||
|
||||
exports.dockerTimeout = dockerTimeout = 2000;
|
||||
|
||||
exports.filterOutSupervisorContainer = filterOutSupervisorContainer = function(container) {
|
||||
var i, len, name, ref;
|
||||
ref = container.Names;
|
||||
for (i = 0, len = ref.length; i < len; i++) {
|
||||
name = ref[i];
|
||||
if (name.includes('resin_supervisor')) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
};
|
||||
|
||||
exports.selectContainerFromDevice = Promise.method(function(deviceIp, filterSupervisor) {
|
||||
var docker;
|
||||
if (filterSupervisor == null) {
|
||||
filterSupervisor = false;
|
||||
}
|
||||
docker = new Docker({
|
||||
host: deviceIp,
|
||||
port: dockerPort,
|
||||
timeout: dockerTimeout
|
||||
});
|
||||
return docker.listContainersAsync({
|
||||
all: true
|
||||
}).filter(function(container) {
|
||||
if (!filterSupervisor) {
|
||||
return true;
|
||||
}
|
||||
return filterOutSupervisorContainer(container);
|
||||
}).then(function(containers) {
|
||||
if (_.isEmpty(containers)) {
|
||||
throw new Error("No containers found in " + deviceIp);
|
||||
}
|
||||
return form.ask({
|
||||
message: 'Select a container',
|
||||
type: 'list',
|
||||
choices: _.map(containers, function(container) {
|
||||
var containerName, containerStatus, shortContainerId;
|
||||
containerName = container.Names[0] || 'Untitled';
|
||||
shortContainerId = ('' + container.Id).substr(0, 11);
|
||||
containerStatus = container.Status;
|
||||
return {
|
||||
name: containerName + " (" + shortContainerId + ") - " + containerStatus,
|
||||
value: container.Id
|
||||
};
|
||||
})
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
exports.pipeContainerStream = Promise.method(function(arg) {
|
||||
var container, deviceIp, docker, follow, name, outStream, ref;
|
||||
deviceIp = arg.deviceIp, name = arg.name, outStream = arg.outStream, follow = (ref = arg.follow) != null ? ref : false;
|
||||
docker = new Docker({
|
||||
host: deviceIp,
|
||||
port: dockerPort
|
||||
});
|
||||
container = docker.getContainer(name);
|
||||
return container.inspectAsync().then(function(containerInfo) {
|
||||
var ref1;
|
||||
return containerInfo != null ? (ref1 = containerInfo.State) != null ? ref1.Running : void 0 : void 0;
|
||||
}).then(function(isRunning) {
|
||||
return container.attachAsync({
|
||||
logs: !follow || !isRunning,
|
||||
stream: follow && isRunning,
|
||||
stdout: true,
|
||||
stderr: true
|
||||
});
|
||||
}).then(function(containerStream) {
|
||||
return containerStream.pipe(outStream);
|
||||
})["catch"](function(err) {
|
||||
err = '' + err.statusCode;
|
||||
if (err === '404') {
|
||||
return console.log(chalk.red.bold("Container '" + name + "' not found."));
|
||||
}
|
||||
throw err;
|
||||
});
|
||||
});
|
||||
|
||||
exports.getSubShellCommand = require('../../utils/helpers').getSubShellCommand;
|
@ -1,210 +0,0 @@
|
||||
// Generated by CoffeeScript 1.12.7
|
||||
|
||||
/*
|
||||
Copyright 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 BOOT_PARTITION, CONNECTIONS_FOLDER, CONNECTION_FILE, getConfiguration, getConfigurationSchema, inquirerOptions, prepareConnectionFile, removeHostname;
|
||||
|
||||
BOOT_PARTITION = {
|
||||
primary: 1
|
||||
};
|
||||
|
||||
CONNECTIONS_FOLDER = '/system-connections';
|
||||
|
||||
getConfigurationSchema = function(connnectionFileName) {
|
||||
if (connnectionFileName == null) {
|
||||
connnectionFileName = 'resin-wifi';
|
||||
}
|
||||
return {
|
||||
mapper: [
|
||||
{
|
||||
template: {
|
||||
persistentLogging: '{{persistentLogging}}'
|
||||
},
|
||||
domain: [['config_json', 'persistentLogging']]
|
||||
}, {
|
||||
template: {
|
||||
hostname: '{{hostname}}'
|
||||
},
|
||||
domain: [['config_json', 'hostname']]
|
||||
}, {
|
||||
template: {
|
||||
wifi: {
|
||||
ssid: '{{networkSsid}}'
|
||||
},
|
||||
'wifi-security': {
|
||||
psk: '{{networkKey}}'
|
||||
}
|
||||
},
|
||||
domain: [['system_connections', connnectionFileName, 'wifi'], ['system_connections', connnectionFileName, 'wifi-security']]
|
||||
}
|
||||
],
|
||||
files: {
|
||||
system_connections: {
|
||||
fileset: true,
|
||||
type: 'ini',
|
||||
location: {
|
||||
path: CONNECTIONS_FOLDER.slice(1),
|
||||
partition: BOOT_PARTITION
|
||||
}
|
||||
},
|
||||
config_json: {
|
||||
type: 'json',
|
||||
location: {
|
||||
path: 'config.json',
|
||||
partition: BOOT_PARTITION
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
inquirerOptions = function(data) {
|
||||
return [
|
||||
{
|
||||
message: 'Network SSID',
|
||||
type: 'input',
|
||||
name: 'networkSsid',
|
||||
"default": data.networkSsid
|
||||
}, {
|
||||
message: 'Network Key',
|
||||
type: 'input',
|
||||
name: 'networkKey',
|
||||
"default": data.networkKey
|
||||
}, {
|
||||
message: 'Do you want to set advanced settings?',
|
||||
type: 'confirm',
|
||||
name: 'advancedSettings',
|
||||
"default": false
|
||||
}, {
|
||||
message: 'Device Hostname',
|
||||
type: 'input',
|
||||
name: 'hostname',
|
||||
"default": data.hostname,
|
||||
when: function(answers) {
|
||||
return answers.advancedSettings;
|
||||
}
|
||||
}, {
|
||||
message: 'Do you want to enable persistent logging?',
|
||||
type: 'confirm',
|
||||
name: 'persistentLogging',
|
||||
"default": data.persistentLogging,
|
||||
when: function(answers) {
|
||||
return answers.advancedSettings;
|
||||
}
|
||||
}
|
||||
];
|
||||
};
|
||||
|
||||
getConfiguration = function(data) {
|
||||
var _, inquirer;
|
||||
_ = require('lodash');
|
||||
inquirer = require('inquirer');
|
||||
data = _.assign(data, {
|
||||
persistentLogging: data.persistentLogging || false
|
||||
});
|
||||
return inquirer.prompt(inquirerOptions(data)).then(function(answers) {
|
||||
return _.merge(data, answers);
|
||||
});
|
||||
};
|
||||
|
||||
CONNECTION_FILE = '[connection]\nid=resin-wifi\ntype=wifi\n\n[wifi]\nhidden=true\nmode=infrastructure\nssid=My_Wifi_Ssid\n\n[wifi-security]\nauth-alg=open\nkey-mgmt=wpa-psk\npsk=super_secret_wifi_password\n\n[ipv4]\nmethod=auto\n\n[ipv6]\naddr-gen-mode=stable-privacy\nmethod=auto';
|
||||
|
||||
|
||||
/*
|
||||
* if the `resin-wifi` file exists (previously configured image or downloaded from the UI) it's used and reconfigured
|
||||
* if the `resin-sample.ignore` exists it's copied to `resin-wifi`
|
||||
* if the `resin-sample` exists it's reconfigured (legacy mode, will be removed eventually)
|
||||
* otherwise, the new file is created
|
||||
*/
|
||||
|
||||
prepareConnectionFile = function(target) {
|
||||
var _, imagefs;
|
||||
_ = require('lodash');
|
||||
imagefs = require('resin-image-fs');
|
||||
return imagefs.listDirectory({
|
||||
image: target,
|
||||
partition: BOOT_PARTITION,
|
||||
path: CONNECTIONS_FOLDER
|
||||
}).then(function(files) {
|
||||
if (_.includes(files, 'resin-wifi')) {
|
||||
return null;
|
||||
}
|
||||
if (_.includes(files, 'resin-sample.ignore')) {
|
||||
return imagefs.copy({
|
||||
image: target,
|
||||
partition: BOOT_PARTITION,
|
||||
path: CONNECTIONS_FOLDER + "/resin-sample.ignore"
|
||||
}, {
|
||||
image: target,
|
||||
partition: BOOT_PARTITION,
|
||||
path: CONNECTIONS_FOLDER + "/resin-wifi"
|
||||
}).thenReturn(null);
|
||||
}
|
||||
if (_.includes(files, 'resin-sample')) {
|
||||
return 'resin-sample';
|
||||
}
|
||||
return imagefs.writeFile({
|
||||
image: target,
|
||||
partition: BOOT_PARTITION,
|
||||
path: CONNECTIONS_FOLDER + "/resin-wifi"
|
||||
}, CONNECTION_FILE).thenReturn(null);
|
||||
}).then(function(connectionFileName) {
|
||||
return getConfigurationSchema(connectionFileName);
|
||||
});
|
||||
};
|
||||
|
||||
removeHostname = function(schema) {
|
||||
var _;
|
||||
_ = require('lodash');
|
||||
return schema.mapper = _.reject(schema.mapper, function(mapper) {
|
||||
return _.isEqual(Object.keys(mapper.template), ['hostname']);
|
||||
});
|
||||
};
|
||||
|
||||
module.exports = {
|
||||
signature: 'local configure <target>',
|
||||
description: '(Re)configure a resinOS drive or image',
|
||||
help: 'Use this command to configure or reconfigure a resinOS drive or image.\n\nExamples:\n\n $ resin local configure /dev/sdc\n $ resin local configure path/to/image.img',
|
||||
root: true,
|
||||
action: function(params, options, done) {
|
||||
var Promise, denymount, isMountedAsync, reconfix, umount, umountAsync;
|
||||
Promise = require('bluebird');
|
||||
umount = require('umount');
|
||||
umountAsync = Promise.promisify(umount.umount);
|
||||
isMountedAsync = Promise.promisify(umount.isMounted);
|
||||
reconfix = require('reconfix');
|
||||
denymount = Promise.promisify(require('denymount'));
|
||||
return prepareConnectionFile(params.target).tap(function() {
|
||||
return isMountedAsync(params.target).then(function(isMounted) {
|
||||
if (!isMounted) {
|
||||
return;
|
||||
}
|
||||
return umountAsync(params.target);
|
||||
});
|
||||
}).then(function(configurationSchema) {
|
||||
return denymount(params.target, function(cb) {
|
||||
return reconfix.readConfiguration(configurationSchema, params.target).then(getConfiguration).then(function(answers) {
|
||||
if (!answers.hostname) {
|
||||
removeHostname(configurationSchema);
|
||||
}
|
||||
return reconfix.writeConfiguration(configurationSchema, answers, params.target);
|
||||
}).asCallback(cb);
|
||||
});
|
||||
}).then(function() {
|
||||
return console.log('Done!');
|
||||
}).asCallback(done);
|
||||
}
|
||||
};
|
@ -1,120 +0,0 @@
|
||||
// Generated by CoffeeScript 1.12.7
|
||||
|
||||
/*
|
||||
Copyright 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.
|
||||
*/
|
||||
module.exports = {
|
||||
signature: 'local flash <image>',
|
||||
description: 'Flash an image to a drive',
|
||||
help: 'Use this command to flash a resinOS image to a drive.\n\nExamples:\n\n $ resin local flash path/to/resinos.img\n $ resin local flash path/to/resinos.img --drive /dev/disk2\n $ resin local flash path/to/resinos.img --drive /dev/disk2 --yes',
|
||||
options: [
|
||||
{
|
||||
signature: 'yes',
|
||||
boolean: true,
|
||||
description: 'confirm non-interactively',
|
||||
alias: 'y'
|
||||
}, {
|
||||
signature: 'drive',
|
||||
parameter: 'drive',
|
||||
description: 'drive',
|
||||
alias: 'd'
|
||||
}
|
||||
],
|
||||
root: true,
|
||||
action: function(params, options, done) {
|
||||
var Promise, _, chalk, driveListAsync, form, fs, imageWrite, os, umountAsync, visuals;
|
||||
_ = require('lodash');
|
||||
os = require('os');
|
||||
Promise = require('bluebird');
|
||||
umountAsync = Promise.promisify(require('umount').umount);
|
||||
fs = Promise.promisifyAll(require('fs'));
|
||||
driveListAsync = Promise.promisify(require('drivelist').list);
|
||||
chalk = require('chalk');
|
||||
visuals = require('resin-cli-visuals');
|
||||
form = require('resin-cli-form');
|
||||
imageWrite = require('etcher-image-write');
|
||||
return form.run([
|
||||
{
|
||||
message: 'Select drive',
|
||||
type: 'drive',
|
||||
name: 'drive'
|
||||
}, {
|
||||
message: 'This will erase the selected drive. Are you sure?',
|
||||
type: 'confirm',
|
||||
name: 'yes',
|
||||
"default": false
|
||||
}
|
||||
], {
|
||||
override: {
|
||||
drive: options.drive,
|
||||
yes: options.yes || void 0
|
||||
}
|
||||
}).then(function(answers) {
|
||||
if (answers.yes !== true) {
|
||||
console.log(chalk.red.bold('Aborted image flash'));
|
||||
process.exit(0);
|
||||
}
|
||||
return driveListAsync().then(function(drives) {
|
||||
var selectedDrive;
|
||||
selectedDrive = _.find(drives, {
|
||||
device: answers.drive
|
||||
});
|
||||
if (selectedDrive == null) {
|
||||
throw new Error("Drive not found: " + answers.drive);
|
||||
}
|
||||
return selectedDrive;
|
||||
});
|
||||
}).then(function(selectedDrive) {
|
||||
var progressBars;
|
||||
progressBars = {
|
||||
write: new visuals.Progress('Flashing'),
|
||||
check: new visuals.Progress('Validating')
|
||||
};
|
||||
return umountAsync(selectedDrive.device).then(function() {
|
||||
return Promise.props({
|
||||
imageSize: fs.statAsync(params.image).get('size'),
|
||||
imageStream: Promise.resolve(fs.createReadStream(params.image)),
|
||||
driveFileDescriptor: fs.openAsync(selectedDrive.raw, 'rs+')
|
||||
});
|
||||
}).then(function(results) {
|
||||
return imageWrite.write({
|
||||
fd: results.driveFileDescriptor,
|
||||
device: selectedDrive.raw,
|
||||
size: selectedDrive.size
|
||||
}, {
|
||||
stream: results.imageStream,
|
||||
size: results.imageSize
|
||||
}, {
|
||||
check: true
|
||||
});
|
||||
}).then(function(writer) {
|
||||
return new Promise(function(resolve, reject) {
|
||||
writer.on('progress', function(state) {
|
||||
return progressBars[state.type].update(state);
|
||||
});
|
||||
writer.on('error', reject);
|
||||
return writer.on('done', resolve);
|
||||
});
|
||||
}).then(function() {
|
||||
var ejectAsync;
|
||||
if ((os.platform() === 'win32') && (selectedDrive.mountpoint != null)) {
|
||||
ejectAsync = Promise.promisify(require('removedrive').eject);
|
||||
return ejectAsync(selectedDrive.mountpoint);
|
||||
}
|
||||
return umountAsync(selectedDrive.device);
|
||||
});
|
||||
}).asCallback(done);
|
||||
}
|
||||
};
|
@ -1,30 +0,0 @@
|
||||
// Generated by CoffeeScript 1.12.7
|
||||
|
||||
/*
|
||||
Copyright 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.
|
||||
*/
|
||||
exports.configure = require('./configure');
|
||||
|
||||
exports.flash = require('./flash');
|
||||
|
||||
exports.logs = require('./logs');
|
||||
|
||||
exports.scan = require('./scan');
|
||||
|
||||
exports.ssh = require('./ssh');
|
||||
|
||||
exports.push = require('./push');
|
||||
|
||||
exports.stop = require('./stop');
|
@ -1,65 +0,0 @@
|
||||
// Generated by CoffeeScript 1.12.7
|
||||
|
||||
/*
|
||||
Copyright 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.
|
||||
*/
|
||||
module.exports = {
|
||||
signature: 'local logs [deviceIp]',
|
||||
description: 'Get or attach to logs of a running container on a resinOS device',
|
||||
help: '\nExamples:\n\n $ resin local logs\n $ resin local logs -f\n $ resin local logs 192.168.1.10\n $ resin local logs 192.168.1.10 -f\n $ resin local logs 192.168.1.10 -f --app-name myapp',
|
||||
options: [
|
||||
{
|
||||
signature: 'follow',
|
||||
boolean: true,
|
||||
description: 'follow log',
|
||||
alias: 'f'
|
||||
}, {
|
||||
signature: 'app-name',
|
||||
parameter: 'name',
|
||||
description: 'name of container to get logs from',
|
||||
alias: 'a'
|
||||
}
|
||||
],
|
||||
root: true,
|
||||
action: function(params, options, done) {
|
||||
var Promise, forms, pipeContainerStream, ref, selectContainerFromDevice;
|
||||
Promise = require('bluebird');
|
||||
forms = require('resin-sync').forms;
|
||||
ref = require('./common'), selectContainerFromDevice = ref.selectContainerFromDevice, pipeContainerStream = ref.pipeContainerStream;
|
||||
return Promise["try"](function() {
|
||||
if (params.deviceIp == null) {
|
||||
return forms.selectLocalResinOsDevice();
|
||||
}
|
||||
return params.deviceIp;
|
||||
}).then((function(_this) {
|
||||
return function(deviceIp) {
|
||||
_this.deviceIp = deviceIp;
|
||||
if (options['app-name'] == null) {
|
||||
return selectContainerFromDevice(_this.deviceIp);
|
||||
}
|
||||
return options['app-name'];
|
||||
};
|
||||
})(this)).then((function(_this) {
|
||||
return function(appName) {
|
||||
return pipeContainerStream({
|
||||
deviceIp: _this.deviceIp,
|
||||
name: appName,
|
||||
outStream: process.stdout,
|
||||
follow: options['follow']
|
||||
});
|
||||
};
|
||||
})(this));
|
||||
}
|
||||
};
|
@ -1,61 +0,0 @@
|
||||
// Generated by CoffeeScript 1.12.7
|
||||
|
||||
/*
|
||||
Copyright 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.
|
||||
*/
|
||||
module.exports = {
|
||||
signature: 'local promote [deviceIp]',
|
||||
description: 'Promote a resinOS device',
|
||||
help: 'Warning: \'resin promote\' requires an openssh-compatible client to be correctly\ninstalled in your shell environment. For more information (including Windows\nsupport) please check the README here: https://github.com/resin-io/resin-cli\n\nUse this command to promote your device.\n\nPromoting a device will provision it onto the Resin platform,\nconverting it from an unmanaged device to a managed device.\n\nExamples:\n\n $ resin local promote\n $ resin local promote --port 22222\n $ resin local promote --verbose',
|
||||
options: [
|
||||
{
|
||||
signature: 'verbose',
|
||||
boolean: true,
|
||||
description: 'increase verbosity',
|
||||
alias: 'v'
|
||||
}, {
|
||||
signature: 'port',
|
||||
parameter: 'port',
|
||||
description: 'ssh port number (default: 22222)',
|
||||
alias: 'p'
|
||||
}
|
||||
],
|
||||
root: true,
|
||||
action: function(params, options, done) {
|
||||
var Promise, _, child_process, forms, getSubShellCommand, verbose;
|
||||
child_process = require('child_process');
|
||||
Promise = require('bluebird');
|
||||
_ = require('lodash');
|
||||
forms = require('resin-sync').forms;
|
||||
getSubShellCommand = require('./common').getSubShellCommand;
|
||||
if (options.port == null) {
|
||||
options.port = 22222;
|
||||
}
|
||||
verbose = options.verbose ? '-vvv' : '';
|
||||
return Promise["try"](function() {
|
||||
return params.deviceIp != null ? params.deviceIp : params.deviceIp = forms.selectLocalResinOsDevice();
|
||||
}).then(function(deviceIp) {
|
||||
var command, subShellCommand;
|
||||
_.assign(options, {
|
||||
deviceIp: deviceIp
|
||||
});
|
||||
command = "ssh " + verbose + " -t -p " + options.port + " -o LogLevel=ERROR -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null root@" + options.deviceIp + " -- \"resin-provision interactive\"";
|
||||
subShellCommand = getSubShellCommand(command);
|
||||
return child_process.spawn(subShellCommand.program, subShellCommand.args, {
|
||||
stdio: 'inherit'
|
||||
});
|
||||
}).nodeify(done);
|
||||
}
|
||||
};
|
@ -1,31 +0,0 @@
|
||||
// Generated by CoffeeScript 1.12.7
|
||||
|
||||
/*
|
||||
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 _, resinPush, resinPushHelp;
|
||||
|
||||
_ = require('lodash');
|
||||
|
||||
resinPush = require('resin-sync').capitano('resin-toolbox');
|
||||
|
||||
resinPushHelp = 'Warning: \'resin local push\' requires an openssh-compatible client and \'rsync\' to\nbe correctly installed in your shell environment. For more information (including\nWindows support) please check the README here: https://github.com/resin-io/resin-cli\n\nUse this command to push your local changes to a container on a LAN-accessible resinOS device on the fly.\n\nIf `Dockerfile` or any file in the \'build-triggers\' list is changed,\na new container will be built and run on your device.\nIf not, changes will simply be synced with `rsync` into the application container.\n\nAfter every \'resin local push\' the updated settings will be saved in\n\'<source>/.resin-sync.yml\' and will be used in later invocations. You can\nalso change any option by editing \'.resin-sync.yml\' directly.\n\nHere is an example \'.resin-sync.yml\' :\n\n $ cat $PWD/.resin-sync.yml\n destination: \'/usr/src/app\'\n before: \'echo Hello\'\n after: \'echo Done\'\n ignore:\n - .git\n - node_modules/\n\nCommand line options have precedence over the ones saved in \'.resin-sync.yml\'.\n\nIf \'.gitignore\' is found in the source directory then all explicitly listed files will be\nexcluded when using rsync to update the container. You can choose to change this default behavior with the\n\'--skip-gitignore\' option.\n\nExamples:\n\n $ resin local push\n $ resin local push --app-name test-server --build-triggers package.json,requirements.txt\n $ resin local push --force-build\n $ resin local push --force-build --skip-logs\n $ resin local push --ignore lib/\n $ resin local push --verbose false\n $ resin local push 192.168.2.10 --source . --destination /usr/src/app\n $ resin local push 192.168.2.10 -s /home/user/myResinProject -d /usr/src/app --before \'echo Hello\' --after \'echo Done\'';
|
||||
|
||||
module.exports = _.assign(resinPush, {
|
||||
signature: 'local push [deviceIp]',
|
||||
help: resinPushHelp,
|
||||
primary: true,
|
||||
root: true
|
||||
});
|
@ -1,112 +0,0 @@
|
||||
// Generated by CoffeeScript 1.12.7
|
||||
|
||||
/*
|
||||
Copyright 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 dockerInfoProperties, dockerVersionProperties;
|
||||
|
||||
dockerInfoProperties = ['Containers', 'ContainersRunning', 'ContainersPaused', 'ContainersStopped', 'Images', 'Driver', 'SystemTime', 'KernelVersion', 'OperatingSystem', 'Architecture'];
|
||||
|
||||
dockerVersionProperties = ['Version', 'ApiVersion'];
|
||||
|
||||
module.exports = {
|
||||
signature: 'local scan',
|
||||
description: 'Scan for resinOS devices in your local network',
|
||||
help: '\nExamples:\n\n $ resin local scan\n $ resin local scan --timeout 120\n $ resin local scan --verbose',
|
||||
options: [
|
||||
{
|
||||
signature: 'verbose',
|
||||
boolean: true,
|
||||
description: 'Display full info',
|
||||
alias: 'v'
|
||||
}, {
|
||||
signature: 'timeout',
|
||||
parameter: 'timeout',
|
||||
description: 'Scan timeout in seconds',
|
||||
alias: 't'
|
||||
}
|
||||
],
|
||||
primary: true,
|
||||
root: true,
|
||||
action: function(params, options, done) {
|
||||
var Docker, Promise, SpinnerPromise, _, discover, dockerPort, dockerTimeout, prettyjson, ref;
|
||||
Promise = require('bluebird');
|
||||
_ = require('lodash');
|
||||
prettyjson = require('prettyjson');
|
||||
Docker = require('docker-toolbelt');
|
||||
discover = require('resin-sync').discover;
|
||||
SpinnerPromise = require('resin-cli-visuals').SpinnerPromise;
|
||||
ref = require('./common'), dockerPort = ref.dockerPort, dockerTimeout = ref.dockerTimeout;
|
||||
if (options.timeout != null) {
|
||||
options.timeout *= 1000;
|
||||
}
|
||||
return Promise["try"](function() {
|
||||
return new SpinnerPromise({
|
||||
promise: discover.discoverLocalResinOsDevices(options.timeout),
|
||||
startMessage: 'Scanning for local resinOS devices..',
|
||||
stopMessage: 'Reporting scan results'
|
||||
});
|
||||
}).filter(function(arg) {
|
||||
var address;
|
||||
address = arg.address;
|
||||
return Promise["try"](function() {
|
||||
var docker;
|
||||
docker = new Docker({
|
||||
host: address,
|
||||
port: dockerPort,
|
||||
timeout: dockerTimeout
|
||||
});
|
||||
return docker.pingAsync();
|
||||
})["return"](true).catchReturn(false);
|
||||
}).tap(function(devices) {
|
||||
if (_.isEmpty(devices)) {
|
||||
throw new Error('Could not find any resinOS devices in the local network');
|
||||
}
|
||||
}).map(function(arg) {
|
||||
var address, docker, host;
|
||||
host = arg.host, address = arg.address;
|
||||
docker = new Docker({
|
||||
host: address,
|
||||
port: dockerPort,
|
||||
timeout: dockerTimeout
|
||||
});
|
||||
return Promise.props({
|
||||
dockerInfo: docker.infoAsync().catchReturn('Could not get Docker info'),
|
||||
dockerVersion: docker.versionAsync().catchReturn('Could not get Docker version')
|
||||
}).then(function(arg1) {
|
||||
var dockerInfo, dockerVersion;
|
||||
dockerInfo = arg1.dockerInfo, dockerVersion = arg1.dockerVersion;
|
||||
if (!options.verbose) {
|
||||
if (_.isObject(dockerInfo)) {
|
||||
dockerInfo = _.pick(dockerInfo, dockerInfoProperties);
|
||||
}
|
||||
if (_.isObject(dockerVersion)) {
|
||||
dockerVersion = _.pick(dockerVersion, dockerVersionProperties);
|
||||
}
|
||||
}
|
||||
return {
|
||||
host: host,
|
||||
address: address,
|
||||
dockerInfo: dockerInfo,
|
||||
dockerVersion: dockerVersion
|
||||
};
|
||||
});
|
||||
}).then(function(devicesInfo) {
|
||||
return console.log(prettyjson.render(devicesInfo, {
|
||||
noColor: true
|
||||
}));
|
||||
}).nodeify(done);
|
||||
}
|
||||
};
|
@ -1,90 +0,0 @@
|
||||
// Generated by CoffeeScript 1.12.7
|
||||
|
||||
/*
|
||||
Copyright 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.
|
||||
*/
|
||||
module.exports = {
|
||||
signature: 'local ssh [deviceIp]',
|
||||
description: 'Get a shell into a resinOS device',
|
||||
help: 'Warning: \'resin local ssh\' requires an openssh-compatible client to be correctly\ninstalled in your shell environment. For more information (including Windows\nsupport) please check the README here: https://github.com/resin-io/resin-cli\n\nUse this command to get a shell into the running application container of\nyour device.\n\nThe \'--host\' option will get you a shell into the Host OS of the resinOS device.\nNo option will return a list of containers to enter or you can explicitly select\none by passing its name to the --container option\n\nExamples:\n\n $ resin local ssh\n $ resin local ssh --host\n $ resin local ssh --container chaotic_water\n $ resin local ssh --container chaotic_water --port 22222\n $ resin local ssh --verbose',
|
||||
options: [
|
||||
{
|
||||
signature: 'verbose',
|
||||
boolean: true,
|
||||
description: 'increase verbosity',
|
||||
alias: 'v'
|
||||
}, {
|
||||
signature: 'host',
|
||||
boolean: true,
|
||||
description: 'get a shell into the host OS',
|
||||
alias: 's'
|
||||
}, {
|
||||
signature: 'container',
|
||||
parameter: 'container',
|
||||
"default": null,
|
||||
description: 'name of container to access',
|
||||
alias: 'c'
|
||||
}, {
|
||||
signature: 'port',
|
||||
parameter: 'port',
|
||||
description: 'ssh port number (default: 22222)',
|
||||
alias: 'p'
|
||||
}
|
||||
],
|
||||
root: true,
|
||||
action: function(params, options, done) {
|
||||
var Promise, _, child_process, forms, getSubShellCommand, ref, selectContainerFromDevice, verbose;
|
||||
child_process = require('child_process');
|
||||
Promise = require('bluebird');
|
||||
_ = require('lodash');
|
||||
forms = require('resin-sync').forms;
|
||||
ref = require('./common'), selectContainerFromDevice = ref.selectContainerFromDevice, getSubShellCommand = ref.getSubShellCommand;
|
||||
if (options.host === true && (options.container != null)) {
|
||||
throw new Error('Please pass either --host or --container option');
|
||||
}
|
||||
if (options.port == null) {
|
||||
options.port = 22222;
|
||||
}
|
||||
verbose = options.verbose ? '-vvv' : '';
|
||||
return Promise["try"](function() {
|
||||
if (params.deviceIp == null) {
|
||||
return forms.selectLocalResinOsDevice();
|
||||
}
|
||||
return params.deviceIp;
|
||||
}).then(function(deviceIp) {
|
||||
_.assign(options, {
|
||||
deviceIp: deviceIp
|
||||
});
|
||||
if (options.host) {
|
||||
return;
|
||||
}
|
||||
if (options.container == null) {
|
||||
return selectContainerFromDevice(deviceIp);
|
||||
}
|
||||
return options.container;
|
||||
}).then(function(container) {
|
||||
var command, shellCmd, subShellCommand;
|
||||
command = "ssh " + verbose + " -t -p " + options.port + " -o LogLevel=ERROR -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null root@" + options.deviceIp;
|
||||
if (!options.host) {
|
||||
shellCmd = '/bin/sh -c $"\'if [ -e /bin/bash ]; then exec /bin/bash; else exec /bin/sh; fi\'"';
|
||||
command += " docker exec -ti " + container + " " + shellCmd;
|
||||
}
|
||||
subShellCommand = getSubShellCommand(command);
|
||||
return child_process.spawn(subShellCommand.program, subShellCommand.args, {
|
||||
stdio: 'inherit'
|
||||
});
|
||||
}).nodeify(done);
|
||||
}
|
||||
};
|
@ -1,77 +0,0 @@
|
||||
// Generated by CoffeeScript 1.12.7
|
||||
|
||||
/*
|
||||
Copyright 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.
|
||||
*/
|
||||
module.exports = {
|
||||
signature: 'local stop [deviceIp]',
|
||||
description: 'Stop a running container on a resinOS device',
|
||||
help: '\nExamples:\n\n $ resin local stop\n $ resin local stop --app-name myapp\n $ resin local stop --all\n $ resin local stop 192.168.1.10\n $ resin local stop 192.168.1.10 --app-name myapp',
|
||||
options: [
|
||||
{
|
||||
signature: 'all',
|
||||
boolean: true,
|
||||
description: 'stop all containers'
|
||||
}, {
|
||||
signature: 'app-name',
|
||||
parameter: 'name',
|
||||
description: 'name of container to stop',
|
||||
alias: 'a'
|
||||
}
|
||||
],
|
||||
root: true,
|
||||
action: function(params, options, done) {
|
||||
var Promise, ResinLocalDockerUtils, chalk, config, filterOutSupervisorContainer, forms, ref, ref1, selectContainerFromDevice;
|
||||
Promise = require('bluebird');
|
||||
chalk = require('chalk');
|
||||
ref = require('resin-sync'), forms = ref.forms, config = ref.config, ResinLocalDockerUtils = ref.ResinLocalDockerUtils;
|
||||
ref1 = require('./common'), selectContainerFromDevice = ref1.selectContainerFromDevice, filterOutSupervisorContainer = ref1.filterOutSupervisorContainer;
|
||||
return Promise["try"](function() {
|
||||
if (params.deviceIp == null) {
|
||||
return forms.selectLocalResinOsDevice();
|
||||
}
|
||||
return params.deviceIp;
|
||||
}).then((function(_this) {
|
||||
return function(deviceIp) {
|
||||
var ref2, ref3, ymlConfig;
|
||||
_this.deviceIp = deviceIp;
|
||||
_this.docker = new ResinLocalDockerUtils(_this.deviceIp);
|
||||
if (options.all) {
|
||||
return _this.docker.docker.listContainersAsync({
|
||||
all: false
|
||||
}).filter(filterOutSupervisorContainer).then(function(containers) {
|
||||
return Promise.map(containers, function(arg) {
|
||||
var Id, Names;
|
||||
Names = arg.Names, Id = arg.Id;
|
||||
console.log(chalk.yellow.bold("* Stopping container " + Names[0]));
|
||||
return _this.docker.stopContainer(Id);
|
||||
});
|
||||
});
|
||||
}
|
||||
ymlConfig = config.load();
|
||||
_this.appName = (ref2 = options['app-name']) != null ? ref2 : (ref3 = ymlConfig['local_resinos']) != null ? ref3['app-name'] : void 0;
|
||||
return _this.docker.checkForRunningContainer(_this.appName).then(function(isRunning) {
|
||||
if (!isRunning) {
|
||||
return selectContainerFromDevice(_this.deviceIp, true);
|
||||
}
|
||||
console.log(chalk.yellow.bold("* Stopping container " + _this.appName));
|
||||
return _this.appName;
|
||||
}).then(function(runningContainerName) {
|
||||
return _this.docker.stopContainer(runningContainerName);
|
||||
});
|
||||
};
|
||||
})(this));
|
||||
}
|
||||
};
|
@ -1,55 +0,0 @@
|
||||
// Generated by CoffeeScript 1.12.7
|
||||
|
||||
/*
|
||||
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.
|
||||
*/
|
||||
module.exports = {
|
||||
signature: 'logs <uuid>',
|
||||
description: 'show device logs',
|
||||
help: 'Use this command to show logs for a specific device.\n\nBy default, the command prints all log messages and exit.\n\nTo continuously stream output, and see new logs in real time, use the `--tail` option.\n\nNote that for now you need to provide the whole UUID for this command to work correctly.\n\nThis is due to some technical limitations that we plan to address soon.\n\nExamples:\n\n $ resin logs 23c73a1\n $ resin logs 23c73a1',
|
||||
options: [
|
||||
{
|
||||
signature: 'tail',
|
||||
description: 'continuously stream output',
|
||||
boolean: true,
|
||||
alias: 't'
|
||||
}
|
||||
],
|
||||
permission: 'user',
|
||||
primary: true,
|
||||
action: function(params, options, done) {
|
||||
var _, moment, printLine, promise, resin;
|
||||
_ = require('lodash');
|
||||
resin = require('resin-sdk-preconfigured');
|
||||
moment = require('moment');
|
||||
printLine = function(line) {
|
||||
var timestamp;
|
||||
timestamp = moment(line.timestamp).format('DD.MM.YY HH:mm:ss (ZZ)');
|
||||
return console.log(timestamp + " " + line.message);
|
||||
};
|
||||
promise = resin.logs.history(params.uuid).each(printLine);
|
||||
if (!options.tail) {
|
||||
return promise["catch"](done)["finally"](function() {
|
||||
return process.exit(0);
|
||||
});
|
||||
}
|
||||
return promise.then(function() {
|
||||
return resin.logs.subscribe(params.uuid).then(function(logs) {
|
||||
logs.on('line', printLine);
|
||||
return logs.on('error', done);
|
||||
});
|
||||
})["catch"](done);
|
||||
}
|
||||
};
|
@ -1,44 +0,0 @@
|
||||
// Generated by CoffeeScript 1.12.7
|
||||
|
||||
/*
|
||||
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.
|
||||
*/
|
||||
exports.set = {
|
||||
signature: 'note <|note>',
|
||||
description: 'set a device note',
|
||||
help: 'Use this command to set or update a device note.\n\nIf note command isn\'t passed, the tool attempts to read from `stdin`.\n\nTo view the notes, use $ resin device <uuid>.\n\nExamples:\n\n $ resin note "My useful note" --device 7cf02a6\n $ cat note.txt | resin note --device 7cf02a6',
|
||||
options: [
|
||||
{
|
||||
signature: 'device',
|
||||
parameter: 'device',
|
||||
description: 'device uuid',
|
||||
alias: ['d', 'dev'],
|
||||
required: 'You have to specify a device'
|
||||
}
|
||||
],
|
||||
permission: 'user',
|
||||
action: function(params, options, done) {
|
||||
var Promise, _, resin;
|
||||
Promise = require('bluebird');
|
||||
_ = require('lodash');
|
||||
resin = require('resin-sdk-preconfigured');
|
||||
return Promise["try"](function() {
|
||||
if (_.isEmpty(params.note)) {
|
||||
throw new Error('Missing note content');
|
||||
}
|
||||
return resin.models.device.note(options.device, params.note);
|
||||
}).nodeify(done);
|
||||
}
|
||||
};
|
@ -1,286 +0,0 @@
|
||||
// Generated by CoffeeScript 1.12.7
|
||||
|
||||
/*
|
||||
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 INIT_WARNING_MESSAGE, _, buildConfig, commandOptions, formatVersion, resolveVersion;
|
||||
|
||||
commandOptions = require('./command-options');
|
||||
|
||||
_ = require('lodash');
|
||||
|
||||
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') {
|
||||
if (version[0] === 'v') {
|
||||
version = version.slice(1);
|
||||
}
|
||||
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));
|
||||
});
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
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',
|
||||
permission: 'user',
|
||||
options: [
|
||||
{
|
||||
signature: 'output',
|
||||
description: 'output path',
|
||||
parameter: 'output',
|
||||
alias: 'o',
|
||||
required: 'You have to specify the output location'
|
||||
}, commandOptions.osVersion
|
||||
],
|
||||
action: function(params, options, done) {
|
||||
var Promise, displayVersion, fs, manager, rindle, unzip, visuals;
|
||||
Promise = require('bluebird');
|
||||
unzip = require('unzip2');
|
||||
fs = require('fs');
|
||||
rindle = require('rindle');
|
||||
manager = require('resin-image-manager');
|
||||
visuals = require('resin-cli-visuals');
|
||||
console.info("Getting device operating system for " + params.type);
|
||||
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) {
|
||||
var bar, output, spinner;
|
||||
bar = new visuals.Progress("Downloading Device OS" + displayVersion);
|
||||
spinner = new visuals.Spinner("Downloading Device OS" + displayVersion + " (size unknown)");
|
||||
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);
|
||||
}
|
||||
return rindle.wait(stream.pipe(output))["return"](options.output);
|
||||
}).tap(function(output) {
|
||||
return console.info('The image was downloaded successfully');
|
||||
}).nodeify(done);
|
||||
}
|
||||
};
|
||||
|
||||
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 = _.find(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\nExample:\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: [
|
||||
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 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);
|
||||
}
|
||||
};
|
||||
|
||||
exports.configure = {
|
||||
signature: 'os configure <image> [uuid] [deviceApiKey]',
|
||||
description: 'configure an os image',
|
||||
help: 'Use this command to configure a previously downloaded operating system image for\nthe specific device or for an application generally.\n\nNote that device api keys are only supported on ResinOS 2.0.3+.\n\nThis comand still supports the *deprecated* format where the UUID and optionally device key\nare passed directly on the command line, but the recommended way is to pass either an --app or\n--device argument. The deprecated format will be remove in a future release.\n\nExamples:\n\n $ resin os configure ../path/rpi.img --device 7cf02a6\n $ resin os configure ../path/rpi.img --device 7cf02a6 --deviceApiKey <existingDeviceKey>\n $ resin os configure ../path/rpi.img --app MyApp',
|
||||
permission: 'user',
|
||||
options: [
|
||||
commandOptions.advancedConfig, commandOptions.optionalApplication, commandOptions.optionalDevice, commandOptions.optionalDeviceApiKey, {
|
||||
signature: 'config',
|
||||
description: 'path to the config JSON file, see `resin os build-config`',
|
||||
parameter: 'config'
|
||||
}
|
||||
],
|
||||
action: function(params, options, done) {
|
||||
var Promise, configurationResourceType, deviceApiKey, fs, generateApplicationConfig, generateDeviceConfig, helpers, init, patterns, readFileAsync, ref, resin, uuid;
|
||||
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');
|
||||
patterns = require('../utils/patterns');
|
||||
ref = require('../utils/config'), generateDeviceConfig = ref.generateDeviceConfig, generateApplicationConfig = ref.generateApplicationConfig;
|
||||
if (_.filter([options.device, options.application, params.uuid]).length !== 1) {
|
||||
patterns.expectedError('To configure an image, you must provide exactly one of:\n\n* A device, with --device <uuid>\n* An application, with --app <appname>\n* [Deprecated] A device, passing its uuid directly on the command line\n\nSee the help page for examples:\n\n $ resin help os configure');
|
||||
}
|
||||
if (params.uuid) {
|
||||
console.warn('Directly passing a UUID to `resin os configure` is deprecated. Pass it with --uuid <uuid> instead.' + (params.deviceApiKey ? ' Device api keys can be passed with --deviceApiKey.\n' : '\n'));
|
||||
}
|
||||
uuid = options.device || params.uuid;
|
||||
deviceApiKey = options.deviceApiKey || params.deviceApiKey;
|
||||
console.info('Configuring operating system image');
|
||||
configurationResourceType = uuid ? 'device' : 'application';
|
||||
return resin.models[configurationResourceType].get(uuid || options.application).then(function(appOrDevice) {
|
||||
return Promise["try"](function() {
|
||||
if (options.config) {
|
||||
return readFileAsync(options.config, 'utf8').then(JSON.parse);
|
||||
}
|
||||
return buildConfig(params.image, appOrDevice.device_type, options.advanced);
|
||||
}).then(function(answers) {
|
||||
return (configurationResourceType === 'device' ? generateDeviceConfig(appOrDevice, deviceApiKey, answers) : generateApplicationConfig(appOrDevice, answers)).then(function(config) {
|
||||
return init.configure(params.image, appOrDevice.device_type, config, 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" + INIT_WARNING_MESSAGE + "\n\nExamples:\n\n $ resin os initialize ../path/rpi.img --type 'raspberry-pi'",
|
||||
permission: 'user',
|
||||
options: [
|
||||
commandOptions.yes, {
|
||||
signature: 'type',
|
||||
description: 'device type (Check available types with `resin devices supported`)',
|
||||
parameter: 'type',
|
||||
alias: 't',
|
||||
required: 'You have to specify a device type'
|
||||
}, commandOptions.drive
|
||||
],
|
||||
action: function(params, options, done) {
|
||||
var Promise, form, helpers, patterns, umountAsync;
|
||||
Promise = require('bluebird');
|
||||
umountAsync = Promise.promisify(require('umount').umount);
|
||||
form = require('resin-cli-form');
|
||||
patterns = require('../utils/patterns');
|
||||
helpers = require('../utils/helpers');
|
||||
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;
|
||||
}).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);
|
||||
}).tap(function(answers) {
|
||||
return helpers.sudo(['internal', 'osinit', params.image, options.type, JSON.stringify(answers)]);
|
||||
}).then(function(answers) {
|
||||
if (answers.drive == null) {
|
||||
return;
|
||||
}
|
||||
return umountAsync(answers.drive).tap(function() {
|
||||
return console.info("You can safely remove " + answers.drive + " now");
|
||||
});
|
||||
}).nodeify(done);
|
||||
}
|
||||
};
|
@ -1,275 +0,0 @@
|
||||
// Generated by CoffeeScript 1.12.7
|
||||
|
||||
/*
|
||||
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 LATEST, dockerUtils, getApplicationsWithSuccessfulBuilds, offerToDisableAutomaticUpdates, selectApplication, selectApplicationCommit,
|
||||
indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; };
|
||||
|
||||
dockerUtils = require('../utils/docker');
|
||||
|
||||
LATEST = 'latest';
|
||||
|
||||
getApplicationsWithSuccessfulBuilds = function(deviceType) {
|
||||
var preload, resin;
|
||||
preload = require('resin-preload');
|
||||
resin = require('resin-sdk-preconfigured');
|
||||
return resin.pine.get({
|
||||
resource: 'my_application',
|
||||
options: {
|
||||
filter: {
|
||||
device_type: deviceType,
|
||||
build: {
|
||||
$any: {
|
||||
$alias: 'b',
|
||||
$expr: {
|
||||
b: {
|
||||
status: 'success'
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
expand: preload.applicationExpandOptions,
|
||||
select: ['id', 'app_name', 'device_type', 'commit'],
|
||||
orderby: 'app_name asc'
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
selectApplication = function(deviceType) {
|
||||
var applicationInfoSpinner, expectedError, form, visuals;
|
||||
visuals = require('resin-cli-visuals');
|
||||
form = require('resin-cli-form');
|
||||
expectedError = require('../utils/patterns').expectedError;
|
||||
applicationInfoSpinner = new visuals.Spinner('Downloading list of applications and builds.');
|
||||
applicationInfoSpinner.start();
|
||||
return getApplicationsWithSuccessfulBuilds(deviceType).then(function(applications) {
|
||||
applicationInfoSpinner.stop();
|
||||
if (applications.length === 0) {
|
||||
expectedError("You have no apps with successful builds for a '" + deviceType + "' device type.");
|
||||
}
|
||||
return form.ask({
|
||||
message: 'Select an application',
|
||||
type: 'list',
|
||||
choices: applications.map(function(app) {
|
||||
return {
|
||||
name: app.app_name,
|
||||
value: app
|
||||
};
|
||||
})
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
selectApplicationCommit = function(builds) {
|
||||
var DEFAULT_CHOICE, choices, expectedError, form;
|
||||
form = require('resin-cli-form');
|
||||
expectedError = require('../utils/patterns').expectedError;
|
||||
if (builds.length === 0) {
|
||||
expectedError('This application has no successful builds.');
|
||||
}
|
||||
DEFAULT_CHOICE = {
|
||||
'name': LATEST,
|
||||
'value': LATEST
|
||||
};
|
||||
choices = [DEFAULT_CHOICE].concat(builds.map(function(build) {
|
||||
return {
|
||||
name: build.push_timestamp + " - " + build.commit_hash,
|
||||
value: build.commit_hash
|
||||
};
|
||||
}));
|
||||
return form.ask({
|
||||
message: 'Select a build',
|
||||
type: 'list',
|
||||
"default": LATEST,
|
||||
choices: choices
|
||||
});
|
||||
};
|
||||
|
||||
offerToDisableAutomaticUpdates = function(application, commit) {
|
||||
var Promise, form, message, resin;
|
||||
Promise = require('bluebird');
|
||||
resin = require('resin-sdk-preconfigured');
|
||||
form = require('resin-cli-form');
|
||||
if (commit === LATEST || !application.should_track_latest_release) {
|
||||
return Promise.resolve();
|
||||
}
|
||||
message = '\nThis application is set to automatically update all devices to the latest available version.\nThis might be unexpected behaviour: with this enabled, the preloaded device will still\ndownload and install the latest build once it is online.\n\nDo you want to disable automatic updates for this application?';
|
||||
return form.ask({
|
||||
message: message,
|
||||
type: 'confirm'
|
||||
}).then(function(update) {
|
||||
if (!update) {
|
||||
return;
|
||||
}
|
||||
return resin.pine.patch({
|
||||
resource: 'application',
|
||||
id: application.id,
|
||||
body: {
|
||||
should_track_latest_release: false
|
||||
}
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
module.exports = {
|
||||
signature: 'preload <image>',
|
||||
description: '(beta) preload an app on a disk image (or Edison zip archive)',
|
||||
help: 'Warning: "resin preload" requires Docker to be correctly installed in\nyour shell environment. For more information (including Windows support)\nplease check the README here: https://github.com/resin-io/resin-cli .\n\nUse this command to preload an application to a local disk image (or\nEdison zip archive) with a built commit from Resin.io.\nThis can be used with cloud builds, or images deployed with resin deploy.\n\nExamples:\n $ resin preload resin.img --app 1234 --commit e1f2592fc6ee949e68756d4f4a48e49bff8d72a0 --splash-image some-image.png\n $ resin preload resin.img',
|
||||
permission: 'user',
|
||||
primary: true,
|
||||
options: dockerUtils.appendConnectionOptions([
|
||||
{
|
||||
signature: 'app',
|
||||
parameter: 'appId',
|
||||
description: 'id of the application to preload',
|
||||
alias: 'a'
|
||||
}, {
|
||||
signature: 'commit',
|
||||
parameter: 'hash',
|
||||
description: 'a specific application commit to preload, use "latest" to specify the latest commit\n(ignored if no appId is given)',
|
||||
alias: 'c'
|
||||
}, {
|
||||
signature: 'splash-image',
|
||||
parameter: 'splashImage.png',
|
||||
description: 'path to a png image to replace the splash screen',
|
||||
alias: 's'
|
||||
}, {
|
||||
signature: 'dont-check-device-type',
|
||||
boolean: true,
|
||||
description: 'Disables check for matching device types in image and application'
|
||||
}
|
||||
]),
|
||||
action: function(params, options, done) {
|
||||
var Promise, _, errors, expectedError, form, nodeCleanup, preload, progressBars, progressHandler, resin, spinnerHandler, spinners, streamToPromise, visuals;
|
||||
_ = require('lodash');
|
||||
Promise = require('bluebird');
|
||||
resin = require('resin-sdk-preconfigured');
|
||||
streamToPromise = require('stream-to-promise');
|
||||
form = require('resin-cli-form');
|
||||
preload = require('resin-preload');
|
||||
errors = require('resin-errors');
|
||||
visuals = require('resin-cli-visuals');
|
||||
nodeCleanup = require('node-cleanup');
|
||||
expectedError = require('../utils/patterns').expectedError;
|
||||
progressBars = {};
|
||||
progressHandler = function(event) {
|
||||
var progressBar;
|
||||
progressBar = progressBars[event.name];
|
||||
if (!progressBar) {
|
||||
progressBar = progressBars[event.name] = new visuals.Progress(event.name);
|
||||
}
|
||||
return progressBar.update({
|
||||
percentage: event.percentage
|
||||
});
|
||||
};
|
||||
spinners = {};
|
||||
spinnerHandler = function(event) {
|
||||
var spinner;
|
||||
spinner = spinners[event.name];
|
||||
if (!spinner) {
|
||||
spinner = spinners[event.name] = new visuals.Spinner(event.name);
|
||||
}
|
||||
if (event.action === 'start') {
|
||||
return spinner.start();
|
||||
} else {
|
||||
console.log();
|
||||
return spinner.stop();
|
||||
}
|
||||
};
|
||||
options.image = params.image;
|
||||
options.appId = options.app;
|
||||
delete options.app;
|
||||
options.splashImage = options['splash-image'];
|
||||
delete options['splash-image'];
|
||||
if (options['dont-check-device-type'] && !options.appId) {
|
||||
expectedError('You need to specify an app id if you disable the device type check.');
|
||||
}
|
||||
return dockerUtils.getDocker(options).then(function(docker) {
|
||||
var gotSignal, preloader;
|
||||
preloader = new preload.Preloader(resin, docker, options.appId, options.commit, options.image, options.splashImage, options.proxy);
|
||||
gotSignal = false;
|
||||
nodeCleanup(function(exitCode, signal) {
|
||||
if (signal) {
|
||||
gotSignal = true;
|
||||
nodeCleanup.uninstall();
|
||||
preloader.cleanup().then(function() {
|
||||
return process.kill(process.pid, signal);
|
||||
});
|
||||
return false;
|
||||
}
|
||||
});
|
||||
if (process.env.DEBUG) {
|
||||
preloader.stderr.pipe(process.stderr);
|
||||
}
|
||||
preloader.on('progress', progressHandler);
|
||||
preloader.on('spinner', spinnerHandler);
|
||||
return new Promise(function(resolve, reject) {
|
||||
preloader.on('error', reject);
|
||||
return preloader.build().then(function() {
|
||||
return preloader.prepare();
|
||||
}).then(function() {
|
||||
return preloader.getDeviceTypeAndPreloadedBuilds();
|
||||
}).then(function(info) {
|
||||
return Promise["try"](function() {
|
||||
if (options.appId) {
|
||||
return preloader.fetchApplication()["catch"](errors.ResinApplicationNotFound, expectedError);
|
||||
}
|
||||
return selectApplication(info.device_type);
|
||||
}).then(function(application) {
|
||||
preloader.setApplication(application);
|
||||
if (!options['dont-check-device-type'] && info.device_type !== application.device_type) {
|
||||
expectedError("Image device type (" + info.device_type + ") and application device type (" + application.device_type + ") do not match");
|
||||
}
|
||||
return Promise["try"](function() {
|
||||
if (options.commit) {
|
||||
if (options.commit === LATEST && application.commit) {
|
||||
return LATEST;
|
||||
} else if (!_.find(application.build, {
|
||||
commit_hash: options.commit
|
||||
})) {
|
||||
expectedError('There is no build matching this commit');
|
||||
}
|
||||
return options.commit;
|
||||
}
|
||||
return selectApplicationCommit(application.build);
|
||||
}).then(function(commit) {
|
||||
if (commit === LATEST) {
|
||||
preloader.commit = application.commit;
|
||||
} else {
|
||||
preloader.commit = commit;
|
||||
}
|
||||
return offerToDisableAutomaticUpdates(application, commit);
|
||||
});
|
||||
}).then(function() {
|
||||
var builds, ref;
|
||||
builds = info.preloaded_builds.map(function(build) {
|
||||
return build.slice(-preload.BUILD_HASH_LENGTH);
|
||||
});
|
||||
if (ref = preloader.commit, indexOf.call(builds, ref) >= 0) {
|
||||
throw new preload.errors.ResinError('This build is already preloaded in this image.');
|
||||
}
|
||||
return preloader.preload()["catch"](preload.errors.ResinError, expectedError);
|
||||
});
|
||||
}).then(resolve)["catch"](reject);
|
||||
}).then(done)["finally"](function() {
|
||||
if (!gotSignal) {
|
||||
return preloader.cleanup();
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
};
|
@ -1,28 +0,0 @@
|
||||
// Generated by CoffeeScript 1.12.7
|
||||
|
||||
/*
|
||||
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.
|
||||
*/
|
||||
exports.list = {
|
||||
signature: 'settings',
|
||||
description: 'print current settings',
|
||||
help: 'Use this command to display detected settings\n\nExamples:\n\n $ resin settings',
|
||||
action: function(params, options, done) {
|
||||
var prettyjson, resin;
|
||||
resin = require('resin-sdk-preconfigured');
|
||||
prettyjson = require('prettyjson');
|
||||
return resin.settings.getAll().then(prettyjson.render).then(console.log).nodeify(done);
|
||||
}
|
||||
};
|
@ -1,124 +0,0 @@
|
||||
// Generated by CoffeeScript 1.12.7
|
||||
|
||||
/*
|
||||
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.
|
||||
*/
|
||||
module.exports = {
|
||||
signature: 'ssh [uuid]',
|
||||
description: '(beta) get a shell into the running app container of a device',
|
||||
help: 'Warning: \'resin ssh\' requires an openssh-compatible client to be correctly\ninstalled in your shell environment. For more information (including Windows\nsupport) please check the README here: https://github.com/resin-io/resin-cli\n\nUse this command to get a shell into the running application container of\nyour device.\n\nExamples:\n\n $ resin ssh MyApp\n $ resin ssh 7cf02a6\n $ resin ssh 7cf02a6 --port 8080\n $ resin ssh 7cf02a6 -v',
|
||||
permission: 'user',
|
||||
primary: true,
|
||||
options: [
|
||||
{
|
||||
signature: 'port',
|
||||
parameter: 'port',
|
||||
description: 'ssh gateway port',
|
||||
alias: 'p'
|
||||
}, {
|
||||
signature: 'verbose',
|
||||
boolean: true,
|
||||
description: 'increase verbosity',
|
||||
alias: 'v'
|
||||
}, {
|
||||
signature: 'noproxy',
|
||||
boolean: true,
|
||||
description: "don't use the proxy configuration for this connection. Only makes sense if you've configured proxy globally."
|
||||
}
|
||||
],
|
||||
action: function(params, options, done) {
|
||||
var Promise, _, bash, child_process, getSshProxyCommand, getSubShellCommand, hasbin, patterns, proxyConfig, resin, useProxy, verbose;
|
||||
child_process = require('child_process');
|
||||
Promise = require('bluebird');
|
||||
resin = require('resin-sdk-preconfigured');
|
||||
_ = require('lodash');
|
||||
bash = require('bash');
|
||||
hasbin = require('hasbin');
|
||||
getSubShellCommand = require('../utils/helpers').getSubShellCommand;
|
||||
patterns = require('../utils/patterns');
|
||||
if (options.port == null) {
|
||||
options.port = 22;
|
||||
}
|
||||
verbose = options.verbose ? '-vvv' : '';
|
||||
proxyConfig = global.PROXY_CONFIG;
|
||||
useProxy = !!proxyConfig && !options.noproxy;
|
||||
getSshProxyCommand = function(hasTunnelBin) {
|
||||
var i, proxyAuth, proxyCommand, tunnelOptions;
|
||||
if (!useProxy) {
|
||||
return '';
|
||||
}
|
||||
if (!hasTunnelBin) {
|
||||
console.warn('Proxy is enabled but the `proxytunnel` binary cannot be found.\nPlease install it if you want to route the `resin ssh` requests through the proxy.\nAlternatively you can pass `--noproxy` param to the `resin ssh` command to ignore the proxy config\nfor the `ssh` requests.\n\nAttemmpting the unproxied request for now.');
|
||||
return '';
|
||||
}
|
||||
tunnelOptions = {
|
||||
proxy: proxyConfig.host + ":" + proxyConfig.port,
|
||||
dest: '%h:%p'
|
||||
};
|
||||
proxyAuth = proxyConfig.proxyAuth;
|
||||
if (proxyAuth) {
|
||||
i = proxyAuth.indexOf(':');
|
||||
_.assign(tunnelOptions, {
|
||||
user: proxyAuth.substring(0, i),
|
||||
pass: proxyAuth.substring(i + 1)
|
||||
});
|
||||
}
|
||||
proxyCommand = "proxytunnel " + (bash.args(tunnelOptions, '--', '='));
|
||||
return "-o " + (bash.args({
|
||||
ProxyCommand: proxyCommand
|
||||
}, '', '='));
|
||||
};
|
||||
return Promise["try"](function() {
|
||||
if (!params.uuid) {
|
||||
return false;
|
||||
}
|
||||
return resin.models.device.has(params.uuid);
|
||||
}).then(function(uuidExists) {
|
||||
if (uuidExists) {
|
||||
return params.uuid;
|
||||
}
|
||||
return patterns.inferOrSelectDevice();
|
||||
}).then(function(uuid) {
|
||||
console.info("Connecting to: " + uuid);
|
||||
return resin.models.device.get(uuid);
|
||||
}).then(function(device) {
|
||||
if (!device.is_online) {
|
||||
throw new Error('Device is not online');
|
||||
}
|
||||
return Promise.props({
|
||||
username: resin.auth.whoami(),
|
||||
uuid: device.uuid,
|
||||
containerId: resin.models.device.getApplicationInfo(device.uuid).get('containerId'),
|
||||
proxyUrl: resin.settings.get('proxyUrl'),
|
||||
hasTunnelBin: useProxy ? hasbin('proxytunnel') : null
|
||||
}).then(function(arg) {
|
||||
var containerId, hasTunnelBin, proxyUrl, username, uuid;
|
||||
username = arg.username, uuid = arg.uuid, containerId = arg.containerId, proxyUrl = arg.proxyUrl, hasTunnelBin = arg.hasTunnelBin;
|
||||
if (containerId == null) {
|
||||
throw new Error('Did not find running application container');
|
||||
}
|
||||
return Promise["try"](function() {
|
||||
var command, sshProxyCommand, subShellCommand;
|
||||
sshProxyCommand = getSshProxyCommand(hasTunnelBin);
|
||||
command = "ssh " + verbose + " -t -o LogLevel=ERROR -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null " + sshProxyCommand + " -p " + options.port + " " + username + "@ssh." + proxyUrl + " enter " + uuid + " " + containerId;
|
||||
subShellCommand = getSubShellCommand(command);
|
||||
return child_process.spawn(subShellCommand.program, subShellCommand.args, {
|
||||
stdio: 'inherit'
|
||||
});
|
||||
});
|
||||
});
|
||||
}).nodeify(done);
|
||||
}
|
||||
};
|
@ -1,18 +0,0 @@
|
||||
// Generated by CoffeeScript 1.12.7
|
||||
|
||||
/*
|
||||
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.
|
||||
*/
|
||||
module.exports = require('resin-sync').capitano('resin-cli');
|
@ -1,57 +0,0 @@
|
||||
// Generated by CoffeeScript 1.12.7
|
||||
|
||||
/*
|
||||
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,60 +0,0 @@
|
||||
// Generated by CoffeeScript 1.12.7
|
||||
|
||||
/*
|
||||
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.
|
||||
*/
|
||||
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 $ resin quickstart\n $ resin quickstart MyApp',
|
||||
primary: true,
|
||||
action: function(params, options, done) {
|
||||
var Promise, capitanoRunAsync, patterns, resin;
|
||||
Promise = require('bluebird');
|
||||
capitanoRunAsync = Promise.promisify(require('capitano').run);
|
||||
resin = require('resin-sdk-preconfigured');
|
||||
patterns = require('../utils/patterns');
|
||||
return resin.auth.isLoggedIn().then(function(isLoggedIn) {
|
||||
if (isLoggedIn) {
|
||||
return;
|
||||
}
|
||||
console.info('Looks like you\'re not logged in yet!');
|
||||
console.info('Lets go through a quick wizard to get you started.\n');
|
||||
return capitanoRunAsync('login');
|
||||
}).then(function() {
|
||||
if (params.name != null) {
|
||||
return;
|
||||
}
|
||||
return patterns.selectOrCreateApplication().tap(function(applicationName) {
|
||||
return resin.models.application.has(applicationName).then(function(hasApplication) {
|
||||
if (hasApplication) {
|
||||
return applicationName;
|
||||
}
|
||||
return capitanoRunAsync("app create " + applicationName);
|
||||
});
|
||||
}).then(function(applicationName) {
|
||||
return params.name = applicationName;
|
||||
});
|
||||
}).then(function() {
|
||||
return capitanoRunAsync("device init --application " + params.name);
|
||||
}).tap(patterns.awaitDevice).then(function(uuid) {
|
||||
return capitanoRunAsync("device " + uuid);
|
||||
}).then(function() {
|
||||
return resin.models.application.get(params.name);
|
||||
}).then(function(application) {
|
||||
return console.log("Your device is ready to start pushing some code!\n\nCheck our official documentation for more information:\n\n http://docs.resin.io/#/pages/introduction/introduction.md\n\nClone an example or go to an existing application directory and run:\n\n $ git remote add resin " + application.git_repository + "\n $ git push resin master");
|
||||
}).nodeify(done);
|
||||
}
|
||||
};
|
251
build/app.js
251
build/app.js
@ -1,251 +0,0 @@
|
||||
// Generated by CoffeeScript 1.12.7
|
||||
|
||||
/*
|
||||
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 Promise, Raven, _, actions, capitano, capitanoExecuteAsync, errors, events, globalTunnel, plugins, proxy, resin, settings, update, validNodeVersions;
|
||||
|
||||
Raven = require('raven');
|
||||
|
||||
Raven.disableConsoleAlerts();
|
||||
|
||||
Raven.config(require('./config').sentryDsn, {
|
||||
captureUnhandledRejections: true,
|
||||
release: require('../package.json').version
|
||||
}).install(function(logged, error) {
|
||||
console.error(error);
|
||||
return process.exit(1);
|
||||
});
|
||||
|
||||
Raven.setContext({
|
||||
extra: {
|
||||
args: process.argv,
|
||||
node_version: process.version
|
||||
}
|
||||
});
|
||||
|
||||
validNodeVersions = require('../package.json').engines.node;
|
||||
|
||||
if (!require('semver').satisfies(process.version, validNodeVersions)) {
|
||||
console.warn("Warning: this version of Node does not match the requirements of this package.\nThis package expects " + validNodeVersions + ", but you're using " + process.version + ".\nThis may cause unexpected behaviour.\n\nTo upgrade your Node, visit https://nodejs.org/en/download/\n");
|
||||
}
|
||||
|
||||
globalTunnel = require('global-tunnel-ng');
|
||||
|
||||
settings = require('resin-settings-client');
|
||||
|
||||
try {
|
||||
proxy = settings.get('proxy') || null;
|
||||
} catch (error1) {
|
||||
proxy = null;
|
||||
}
|
||||
|
||||
globalTunnel.initialize(proxy);
|
||||
|
||||
global.PROXY_CONFIG = globalTunnel.proxyConfig;
|
||||
|
||||
_ = require('lodash');
|
||||
|
||||
Promise = require('bluebird');
|
||||
|
||||
capitano = require('capitano');
|
||||
|
||||
capitanoExecuteAsync = Promise.promisify(capitano.execute);
|
||||
|
||||
require('resin-sdk').setSharedOptions({
|
||||
apiUrl: settings.get('apiUrl'),
|
||||
imageMakerUrl: settings.get('imageMakerUrl'),
|
||||
dataDirectory: settings.get('dataDirectory'),
|
||||
retries: 2
|
||||
});
|
||||
|
||||
resin = require('resin-sdk-preconfigured');
|
||||
|
||||
actions = require('./actions');
|
||||
|
||||
errors = require('./errors');
|
||||
|
||||
events = require('./events');
|
||||
|
||||
plugins = require('./utils/plugins');
|
||||
|
||||
update = require('./utils/update');
|
||||
|
||||
require('any-promise/register/bluebird');
|
||||
|
||||
capitano.permission('user', function(done) {
|
||||
return resin.auth.isLoggedIn().then(function(isLoggedIn) {
|
||||
if (!isLoggedIn) {
|
||||
throw new Error('You have to log in to continue\n\nRun the following command to go through the login wizard:\n\n $ resin login');
|
||||
}
|
||||
}).nodeify(done);
|
||||
});
|
||||
|
||||
capitano.command({
|
||||
signature: '*',
|
||||
action: function() {
|
||||
return capitano.execute({
|
||||
command: 'help'
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
capitano.globalOption({
|
||||
signature: 'help',
|
||||
boolean: true,
|
||||
alias: 'h'
|
||||
});
|
||||
|
||||
capitano.command(actions.info.version);
|
||||
|
||||
capitano.command(actions.help.help);
|
||||
|
||||
capitano.command(actions.wizard.wizard);
|
||||
|
||||
capitano.command(actions.auth.login);
|
||||
|
||||
capitano.command(actions.auth.logout);
|
||||
|
||||
capitano.command(actions.auth.signup);
|
||||
|
||||
capitano.command(actions.auth.whoami);
|
||||
|
||||
capitano.command(actions.app.create);
|
||||
|
||||
capitano.command(actions.app.list);
|
||||
|
||||
capitano.command(actions.app.remove);
|
||||
|
||||
capitano.command(actions.app.restart);
|
||||
|
||||
capitano.command(actions.app.info);
|
||||
|
||||
capitano.command(actions.device.list);
|
||||
|
||||
capitano.command(actions.device.supported);
|
||||
|
||||
capitano.command(actions.device.rename);
|
||||
|
||||
capitano.command(actions.device.init);
|
||||
|
||||
capitano.command(actions.device.remove);
|
||||
|
||||
capitano.command(actions.device.identify);
|
||||
|
||||
capitano.command(actions.device.reboot);
|
||||
|
||||
capitano.command(actions.device.shutdown);
|
||||
|
||||
capitano.command(actions.device.enableDeviceUrl);
|
||||
|
||||
capitano.command(actions.device.disableDeviceUrl);
|
||||
|
||||
capitano.command(actions.device.getDeviceUrl);
|
||||
|
||||
capitano.command(actions.device.hasDeviceUrl);
|
||||
|
||||
capitano.command(actions.device.register);
|
||||
|
||||
capitano.command(actions.device.move);
|
||||
|
||||
capitano.command(actions.device.info);
|
||||
|
||||
capitano.command(actions.notes.set);
|
||||
|
||||
capitano.command(actions.keys.list);
|
||||
|
||||
capitano.command(actions.keys.add);
|
||||
|
||||
capitano.command(actions.keys.info);
|
||||
|
||||
capitano.command(actions.keys.remove);
|
||||
|
||||
capitano.command(actions.env.list);
|
||||
|
||||
capitano.command(actions.env.add);
|
||||
|
||||
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);
|
||||
|
||||
capitano.command(actions.config.read);
|
||||
|
||||
capitano.command(actions.config.write);
|
||||
|
||||
capitano.command(actions.config.inject);
|
||||
|
||||
capitano.command(actions.config.reconfigure);
|
||||
|
||||
capitano.command(actions.config.generate);
|
||||
|
||||
capitano.command(actions.settings.list);
|
||||
|
||||
capitano.command(actions.logs);
|
||||
|
||||
capitano.command(actions.sync);
|
||||
|
||||
capitano.command(actions.preload);
|
||||
|
||||
capitano.command(actions.ssh);
|
||||
|
||||
capitano.command(actions.local.configure);
|
||||
|
||||
capitano.command(actions.local.flash);
|
||||
|
||||
capitano.command(actions.local.logs);
|
||||
|
||||
capitano.command(actions.local.push);
|
||||
|
||||
capitano.command(actions.local.ssh);
|
||||
|
||||
capitano.command(actions.local.scan);
|
||||
|
||||
capitano.command(actions.local.stop);
|
||||
|
||||
capitano.command(actions.util.availableDrives);
|
||||
|
||||
capitano.command(actions.internal.osInit);
|
||||
|
||||
capitano.command(actions.build);
|
||||
|
||||
capitano.command(actions.deploy);
|
||||
|
||||
update.notify();
|
||||
|
||||
plugins.register(/^resin-plugin-(.+)$/).then(function() {
|
||||
var cli, runCommand;
|
||||
cli = capitano.parse(process.argv);
|
||||
runCommand = function() {
|
||||
var ref, ref1;
|
||||
if ((ref = cli.global) != null ? ref.help : void 0) {
|
||||
return capitanoExecuteAsync({
|
||||
command: "help " + ((ref1 = cli.command) != null ? ref1 : '')
|
||||
});
|
||||
} else {
|
||||
return capitanoExecuteAsync(cli);
|
||||
}
|
||||
};
|
||||
return Promise.all([events.trackCommand(cli), runCommand()]);
|
||||
})["catch"](errors.handle);
|
@ -1,2 +0,0 @@
|
||||
// Generated by CoffeeScript 1.12.7
|
||||
exports.sentryDsn = 'https://56d2a46124614b01b0f4086897e96110:6e175465accc41b595a96947155f61fb@sentry.io/149239';
|
@ -1,45 +0,0 @@
|
||||
// Generated by CoffeeScript 1.12.7
|
||||
|
||||
/*
|
||||
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 Promise, Raven, captureException, chalk, errors, patterns;
|
||||
|
||||
chalk = require('chalk');
|
||||
|
||||
errors = require('resin-cli-errors');
|
||||
|
||||
patterns = require('./utils/patterns');
|
||||
|
||||
Raven = require('raven');
|
||||
|
||||
Promise = require('bluebird');
|
||||
|
||||
captureException = Promise.promisify(Raven.captureException.bind(Raven));
|
||||
|
||||
exports.handle = function(error) {
|
||||
var message;
|
||||
message = errors.interpret(error);
|
||||
if (message == null) {
|
||||
return;
|
||||
}
|
||||
if (process.env.DEBUG) {
|
||||
message = error.stack;
|
||||
}
|
||||
patterns.printErrorMessage(message);
|
||||
return captureException(error).timeout(1000)["catch"](function() {})["finally"](function() {
|
||||
return process.exit(error.exitCode || 1);
|
||||
});
|
||||
};
|
@ -1,49 +0,0 @@
|
||||
// Generated by CoffeeScript 1.12.7
|
||||
var Mixpanel, Promise, Raven, _, packageJSON, resin;
|
||||
|
||||
_ = require('lodash');
|
||||
|
||||
Mixpanel = require('mixpanel');
|
||||
|
||||
Raven = require('raven');
|
||||
|
||||
Promise = require('bluebird');
|
||||
|
||||
resin = require('resin-sdk-preconfigured');
|
||||
|
||||
packageJSON = require('../package.json');
|
||||
|
||||
exports.getLoggerInstance = _.memoize(function() {
|
||||
return resin.models.config.getMixpanelToken().then(Mixpanel.init);
|
||||
});
|
||||
|
||||
exports.trackCommand = function(capitanoCommand) {
|
||||
var capitanoStateGetMatchCommandAsync;
|
||||
capitanoStateGetMatchCommandAsync = Promise.promisify(require('capitano').state.getMatchCommand);
|
||||
return Promise.props({
|
||||
resinUrl: resin.settings.get('resinUrl'),
|
||||
username: resin.auth.whoami().catchReturn(void 0),
|
||||
mixpanel: exports.getLoggerInstance()
|
||||
}).then(function(arg) {
|
||||
var mixpanel, resinUrl, username;
|
||||
username = arg.username, resinUrl = arg.resinUrl, mixpanel = arg.mixpanel;
|
||||
return capitanoStateGetMatchCommandAsync(capitanoCommand.command).then(function(command) {
|
||||
Raven.mergeContext({
|
||||
user: {
|
||||
id: username,
|
||||
username: username
|
||||
}
|
||||
});
|
||||
return mixpanel.track("[CLI] " + (command.signature.toString()), {
|
||||
distinct_id: username,
|
||||
argv: process.argv.join(' '),
|
||||
version: packageJSON.version,
|
||||
node: process.version,
|
||||
arch: process.arch,
|
||||
resinUrl: resinUrl,
|
||||
platform: process.platform,
|
||||
command: capitanoCommand
|
||||
});
|
||||
});
|
||||
}).timeout(100).catchReturn();
|
||||
};
|
@ -1,107 +0,0 @@
|
||||
// Generated by CoffeeScript 1.12.7
|
||||
|
||||
/*
|
||||
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 authenticateWithApplicationKey, authenticateWithDeviceKey;
|
||||
|
||||
exports.generateBaseConfig = function(application, options) {
|
||||
var Promise, _, deviceConfig, resin;
|
||||
Promise = require('bluebird');
|
||||
_ = require('lodash');
|
||||
deviceConfig = require('resin-device-config');
|
||||
resin = require('resin-sdk-preconfigured');
|
||||
options = _.mapValues(options, function(value, key) {
|
||||
if (key === 'appUpdatePollInterval') {
|
||||
return value * 60 * 1000;
|
||||
} else {
|
||||
return value;
|
||||
}
|
||||
});
|
||||
return Promise.props({
|
||||
userId: resin.auth.getUserId(),
|
||||
username: resin.auth.whoami(),
|
||||
apiUrl: resin.settings.get('apiUrl'),
|
||||
vpnUrl: resin.settings.get('vpnUrl'),
|
||||
registryUrl: resin.settings.get('registryUrl'),
|
||||
deltaUrl: resin.settings.get('deltaUrl'),
|
||||
pubNubKeys: resin.models.config.getPubNubKeys(),
|
||||
mixpanelToken: resin.models.config.getMixpanelToken()
|
||||
}).then(function(results) {
|
||||
return deviceConfig.generate({
|
||||
application: application,
|
||||
user: {
|
||||
id: results.userId,
|
||||
username: results.username
|
||||
},
|
||||
endpoints: {
|
||||
api: results.apiUrl,
|
||||
vpn: results.vpnUrl,
|
||||
registry: results.registryUrl,
|
||||
delta: results.deltaUrl
|
||||
},
|
||||
pubnub: results.pubNubKeys,
|
||||
mixpanel: {
|
||||
token: results.mixpanelToken
|
||||
}
|
||||
}, options);
|
||||
});
|
||||
};
|
||||
|
||||
exports.generateApplicationConfig = function(application, options) {
|
||||
return exports.generateBaseConfig(application, options).tap(function(config) {
|
||||
return authenticateWithApplicationKey(config, application.id);
|
||||
});
|
||||
};
|
||||
|
||||
exports.generateDeviceConfig = function(device, deviceApiKey, options) {
|
||||
var resin;
|
||||
resin = require('resin-sdk-preconfigured');
|
||||
return resin.models.application.get(device.application_name).then(function(application) {
|
||||
return exports.generateBaseConfig(application, options).tap(function(config) {
|
||||
if (deviceApiKey != null) {
|
||||
return authenticateWithDeviceKey(config, device.uuid, deviceApiKey);
|
||||
} else {
|
||||
return authenticateWithApplicationKey(config, application.id);
|
||||
}
|
||||
});
|
||||
}).then(function(config) {
|
||||
config.registered_at = Math.floor(Date.now() / 1000);
|
||||
config.deviceId = device.id;
|
||||
config.uuid = device.uuid;
|
||||
return config;
|
||||
});
|
||||
};
|
||||
|
||||
authenticateWithApplicationKey = function(config, applicationNameOrId) {
|
||||
var resin;
|
||||
resin = require('resin-sdk-preconfigured');
|
||||
return resin.models.application.generateApiKey(applicationNameOrId).then(function(apiKey) {
|
||||
config.apiKey = apiKey;
|
||||
return config;
|
||||
});
|
||||
};
|
||||
|
||||
authenticateWithDeviceKey = function(config, uuid, customDeviceApiKey) {
|
||||
var Promise, resin;
|
||||
Promise = require('bluebird');
|
||||
resin = require('resin-sdk-preconfigured');
|
||||
return Promise["try"](function() {
|
||||
return customDeviceApiKey || resin.models.device.generateDeviceKey(uuid);
|
||||
}).then(function(deviceApiKey) {
|
||||
config.deviceApiKey = deviceApiKey;
|
||||
return config;
|
||||
});
|
||||
};
|
@ -1,405 +0,0 @@
|
||||
// Generated by CoffeeScript 1.12.7
|
||||
var QEMU_BIN_NAME, QEMU_VERSION, appendConnectionOptions, cacheHighlightStream, copyQemu, ensureDockerSeemsAccessible, generateConnectOpts, getQemuPath, hasQemu, installQemu, parseBuildArgs, platformNeedsQemu, tarDirectory;
|
||||
|
||||
QEMU_VERSION = 'v2.5.50-resin-execve';
|
||||
|
||||
QEMU_BIN_NAME = 'qemu-execve';
|
||||
|
||||
exports.appendConnectionOptions = appendConnectionOptions = function(opts) {
|
||||
return opts.concat([
|
||||
{
|
||||
signature: 'docker',
|
||||
parameter: 'docker',
|
||||
description: 'Path to a local docker socket',
|
||||
alias: 'P'
|
||||
}, {
|
||||
signature: 'dockerHost',
|
||||
parameter: 'dockerHost',
|
||||
description: 'The address of the host containing the docker daemon',
|
||||
alias: 'h'
|
||||
}, {
|
||||
signature: 'dockerPort',
|
||||
parameter: 'dockerPort',
|
||||
description: 'The port on which the host docker daemon is listening',
|
||||
alias: 'p'
|
||||
}, {
|
||||
signature: 'ca',
|
||||
parameter: 'ca',
|
||||
description: 'Docker host TLS certificate authority file'
|
||||
}, {
|
||||
signature: 'cert',
|
||||
parameter: 'cert',
|
||||
description: 'Docker host TLS certificate file'
|
||||
}, {
|
||||
signature: 'key',
|
||||
parameter: 'key',
|
||||
description: 'Docker host TLS key file'
|
||||
}
|
||||
]);
|
||||
};
|
||||
|
||||
exports.appendOptions = function(opts) {
|
||||
return appendConnectionOptions(opts).concat([
|
||||
{
|
||||
signature: 'tag',
|
||||
parameter: 'tag',
|
||||
description: 'The alias to the generated image',
|
||||
alias: 't'
|
||||
}, {
|
||||
signature: 'buildArg',
|
||||
parameter: 'arg',
|
||||
description: 'Set a build-time variable (eg. "-B \'ARG=value\'"). Can be specified multiple times.',
|
||||
alias: 'B'
|
||||
}, {
|
||||
signature: 'nocache',
|
||||
description: "Don't use docker layer caching when building",
|
||||
boolean: true
|
||||
}, {
|
||||
signature: 'emulated',
|
||||
description: 'Run an emulated build using Qemu',
|
||||
boolean: true,
|
||||
alias: 'e'
|
||||
}, {
|
||||
signature: 'squash',
|
||||
description: 'Squash newly built layers into a single new layer',
|
||||
boolean: true
|
||||
}
|
||||
]);
|
||||
};
|
||||
|
||||
exports.generateConnectOpts = generateConnectOpts = function(opts) {
|
||||
var Promise, _, buildDockerodeOpts, fs;
|
||||
Promise = require('bluebird');
|
||||
buildDockerodeOpts = require('dockerode-options');
|
||||
fs = require('mz/fs');
|
||||
_ = require('lodash');
|
||||
return Promise["try"](function() {
|
||||
var certBodies, connectOpts;
|
||||
connectOpts = {};
|
||||
if ((opts.docker != null) && (opts.dockerHost == null)) {
|
||||
connectOpts.socketPath = opts.docker;
|
||||
} else if ((opts.dockerHost != null) && (opts.docker == null)) {
|
||||
connectOpts.host = opts.dockerHost;
|
||||
connectOpts.port = opts.dockerPort || 2376;
|
||||
} else if ((opts.docker != null) && (opts.dockerHost != null)) {
|
||||
throw new Error("Both a local docker socket and docker host have been provided. Don't know how to continue.");
|
||||
} else if (process.env.DOCKER_HOST) {
|
||||
connectOpts = buildDockerodeOpts(process.env.DOCKER_HOST);
|
||||
} else {
|
||||
connectOpts.socketPath = '/var/run/docker.sock';
|
||||
}
|
||||
if ((opts.ca != null) || (opts.cert != null) || (opts.key != null)) {
|
||||
if (!((opts.ca != null) && (opts.cert != null) && (opts.key != null))) {
|
||||
throw new Error('You must provide a CA, certificate and key in order to use TLS');
|
||||
}
|
||||
certBodies = {
|
||||
ca: fs.readFile(opts.ca, 'utf-8'),
|
||||
cert: fs.readFile(opts.cert, 'utf-8'),
|
||||
key: fs.readFile(opts.key, 'utf-8')
|
||||
};
|
||||
return Promise.props(certBodies).then(function(toMerge) {
|
||||
return _.merge(connectOpts, toMerge);
|
||||
});
|
||||
}
|
||||
return connectOpts;
|
||||
});
|
||||
};
|
||||
|
||||
exports.tarDirectory = tarDirectory = function(dir) {
|
||||
var Promise, fs, getFiles, klaw, pack, path, streamToPromise, tar;
|
||||
Promise = require('bluebird');
|
||||
tar = require('tar-stream');
|
||||
klaw = require('klaw');
|
||||
path = require('path');
|
||||
fs = require('mz/fs');
|
||||
streamToPromise = require('stream-to-promise');
|
||||
getFiles = function() {
|
||||
return streamToPromise(klaw(dir)).filter(function(item) {
|
||||
return !item.stats.isDirectory();
|
||||
}).map(function(item) {
|
||||
return item.path;
|
||||
});
|
||||
};
|
||||
pack = tar.pack();
|
||||
return getFiles(dir).map(function(file) {
|
||||
var relPath;
|
||||
relPath = path.relative(path.resolve(dir), file);
|
||||
return Promise.join(relPath, fs.stat(file), fs.readFile(file), function(filename, stats, data) {
|
||||
return pack.entryAsync({
|
||||
name: filename,
|
||||
size: stats.size,
|
||||
mode: stats.mode
|
||||
}, data);
|
||||
});
|
||||
}).then(function() {
|
||||
pack.finalize();
|
||||
return pack;
|
||||
});
|
||||
};
|
||||
|
||||
cacheHighlightStream = function() {
|
||||
var EOL, colors, es, extractArrowMessage;
|
||||
colors = require('colors/safe');
|
||||
es = require('event-stream');
|
||||
EOL = require('os').EOL;
|
||||
extractArrowMessage = function(message) {
|
||||
var arrowTest, match;
|
||||
arrowTest = /^\s*-+>\s*(.+)/i;
|
||||
if ((match = arrowTest.exec(message))) {
|
||||
return match[1];
|
||||
} else {
|
||||
return void 0;
|
||||
}
|
||||
};
|
||||
return es.mapSync(function(data) {
|
||||
var msg;
|
||||
msg = extractArrowMessage(data);
|
||||
if ((msg != null) && msg.toLowerCase() === 'using cache') {
|
||||
data = colors.bgGreen.black(msg);
|
||||
}
|
||||
return data + EOL;
|
||||
});
|
||||
};
|
||||
|
||||
parseBuildArgs = function(args, onError) {
|
||||
var _, buildArgs;
|
||||
_ = require('lodash');
|
||||
if (!_.isArray(args)) {
|
||||
args = [args];
|
||||
}
|
||||
buildArgs = {};
|
||||
args.forEach(function(str) {
|
||||
var pair;
|
||||
pair = /^([^\s]+?)=(.*)$/.exec(str);
|
||||
if (pair != null) {
|
||||
return buildArgs[pair[1]] = pair[2];
|
||||
} else {
|
||||
return onError(str);
|
||||
}
|
||||
});
|
||||
return buildArgs;
|
||||
};
|
||||
|
||||
exports.runBuild = function(params, options, getBundleInfo, logger) {
|
||||
var Promise, dockerBuild, doodles, es, logs, path, qemuPath, resolver, transpose;
|
||||
Promise = require('bluebird');
|
||||
dockerBuild = require('resin-docker-build');
|
||||
resolver = require('resin-bundle-resolve');
|
||||
es = require('event-stream');
|
||||
doodles = require('resin-doodles');
|
||||
transpose = require('docker-qemu-transpose');
|
||||
path = require('path');
|
||||
if (params.source == null) {
|
||||
params.source = '.';
|
||||
}
|
||||
logs = '';
|
||||
qemuPath = '';
|
||||
return Promise["try"](function() {
|
||||
if (!(options.emulated && platformNeedsQemu())) {
|
||||
return;
|
||||
}
|
||||
return hasQemu().then(function(present) {
|
||||
if (!present) {
|
||||
logger.logInfo('Installing qemu for ARM emulation...');
|
||||
return installQemu();
|
||||
}
|
||||
}).then(function() {
|
||||
return copyQemu(params.source);
|
||||
}).then(function(binPath) {
|
||||
return qemuPath = path.relative(params.source, binPath);
|
||||
});
|
||||
}).then(function() {
|
||||
return tarDirectory(params.source);
|
||||
}).then(function(tarStream) {
|
||||
return new Promise(function(resolve, reject) {
|
||||
var hooks;
|
||||
hooks = {
|
||||
buildSuccess: function(image) {
|
||||
var doodle;
|
||||
doodle = doodles.getDoodle();
|
||||
console.log();
|
||||
console.log(doodle);
|
||||
console.log();
|
||||
return resolve({
|
||||
image: image,
|
||||
log: logs + '\n' + doodle + '\n'
|
||||
});
|
||||
},
|
||||
buildFailure: reject,
|
||||
buildStream: function(stream) {
|
||||
var buildThroughStream, logThroughStream, newStream;
|
||||
if (options.emulated) {
|
||||
logger.logInfo('Running emulated build');
|
||||
}
|
||||
getBundleInfo(options).then(function(info) {
|
||||
var arch, bundle, deviceType;
|
||||
if (info == null) {
|
||||
logger.logWarn('Warning: No architecture/device type or application information provided.\n Dockerfile/project pre-processing will not be performed.');
|
||||
return tarStream;
|
||||
} else {
|
||||
arch = info[0], deviceType = info[1];
|
||||
bundle = new resolver.Bundle(tarStream, deviceType, arch);
|
||||
return resolver.resolveBundle(bundle, resolver.getDefaultResolvers()).then(function(resolved) {
|
||||
logger.logInfo("Building " + resolved.projectType + " project");
|
||||
return resolved.tarStream;
|
||||
});
|
||||
}
|
||||
}).then(function(buildStream) {
|
||||
if (options.emulated && platformNeedsQemu()) {
|
||||
return transpose.transposeTarStream(buildStream, {
|
||||
hostQemuPath: qemuPath,
|
||||
containerQemuPath: "/tmp/" + QEMU_BIN_NAME
|
||||
});
|
||||
} else {
|
||||
return buildStream;
|
||||
}
|
||||
}).then(function(buildStream) {
|
||||
return buildStream.pipe(stream);
|
||||
})["catch"](reject);
|
||||
logThroughStream = es.through(function(data) {
|
||||
logs += data.toString();
|
||||
return this.emit('data', data);
|
||||
});
|
||||
if (options.emulated && platformNeedsQemu()) {
|
||||
buildThroughStream = transpose.getBuildThroughStream({
|
||||
hostQemuPath: qemuPath,
|
||||
containerQemuPath: "/tmp/" + QEMU_BIN_NAME
|
||||
});
|
||||
newStream = stream.pipe(buildThroughStream);
|
||||
} else {
|
||||
newStream = stream;
|
||||
}
|
||||
return newStream.pipe(logThroughStream).pipe(cacheHighlightStream()).pipe(logger.streams.build);
|
||||
}
|
||||
};
|
||||
return generateConnectOpts(options).tap(function(connectOpts) {
|
||||
return ensureDockerSeemsAccessible(connectOpts);
|
||||
}).then(function(connectOpts) {
|
||||
var builder, opts;
|
||||
logger.logDebug('Connecting with the following options:');
|
||||
logger.logDebug(JSON.stringify(connectOpts, null, ' '));
|
||||
builder = new dockerBuild.Builder(connectOpts);
|
||||
opts = {};
|
||||
if (options.tag != null) {
|
||||
opts['t'] = options.tag;
|
||||
}
|
||||
if (options.nocache != null) {
|
||||
opts['nocache'] = true;
|
||||
}
|
||||
if (options.buildArg != null) {
|
||||
opts['buildargs'] = parseBuildArgs(options.buildArg, function(arg) {
|
||||
return logger.logWarn("Could not parse variable: '" + arg + "'");
|
||||
});
|
||||
}
|
||||
if (options.squash != null) {
|
||||
opts['squash'] = true;
|
||||
}
|
||||
return builder.createBuildStream(opts, hooks, reject);
|
||||
});
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
exports.bufferImage = function(docker, imageId, bufferFile) {
|
||||
var Promise, image, imageMetadata, streamUtils;
|
||||
Promise = require('bluebird');
|
||||
streamUtils = require('./streams');
|
||||
image = docker.getImage(imageId);
|
||||
imageMetadata = image.inspectAsync();
|
||||
return Promise.join(image.get(), imageMetadata.get('Size'), function(imageStream, imageSize) {
|
||||
return streamUtils.buffer(imageStream, bufferFile).tap(function(bufferedStream) {
|
||||
return bufferedStream.length = imageSize;
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
exports.getDocker = function(options) {
|
||||
var Docker, Promise;
|
||||
Docker = require('dockerode');
|
||||
Promise = require('bluebird');
|
||||
return generateConnectOpts(options).tap(function(connectOpts) {
|
||||
return ensureDockerSeemsAccessible(connectOpts);
|
||||
}).then(function(connectOpts) {
|
||||
connectOpts['Promise'] = Promise;
|
||||
return new Docker(connectOpts);
|
||||
});
|
||||
};
|
||||
|
||||
ensureDockerSeemsAccessible = function(options) {
|
||||
var fs;
|
||||
fs = require('mz/fs');
|
||||
if (options.socketPath != null) {
|
||||
return fs.access(options.socketPath, (fs.constants || fs).R_OK | (fs.constants || fs).W_OK)["return"](true)["catch"](function(err) {
|
||||
throw new Error("Docker seems to be unavailable (using socket " + options.socketPath + "). Is it installed, and do you have permission to talk to it?");
|
||||
});
|
||||
} else {
|
||||
return Promise.resolve(true);
|
||||
}
|
||||
};
|
||||
|
||||
hasQemu = function() {
|
||||
var fs;
|
||||
fs = require('mz/fs');
|
||||
return getQemuPath().then(fs.stat)["return"](true).catchReturn(false);
|
||||
};
|
||||
|
||||
getQemuPath = function() {
|
||||
var fs, path, resin;
|
||||
resin = require('resin-sdk-preconfigured');
|
||||
path = require('path');
|
||||
fs = require('mz/fs');
|
||||
return resin.settings.get('binDirectory').then(function(binDir) {
|
||||
return fs.access(binDir)["catch"]({
|
||||
code: 'ENOENT'
|
||||
}, function() {
|
||||
return fs.mkdir(binDir);
|
||||
}).then(function() {
|
||||
return path.join(binDir, QEMU_BIN_NAME);
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
platformNeedsQemu = function() {
|
||||
var os;
|
||||
os = require('os');
|
||||
return os.platform() === 'linux';
|
||||
};
|
||||
|
||||
installQemu = function() {
|
||||
var fs, request, zlib;
|
||||
request = require('request');
|
||||
fs = require('fs');
|
||||
zlib = require('zlib');
|
||||
return getQemuPath().then(function(qemuPath) {
|
||||
return new Promise(function(resolve, reject) {
|
||||
var installStream, qemuUrl;
|
||||
installStream = fs.createWriteStream(qemuPath);
|
||||
qemuUrl = "https://github.com/resin-io/qemu/releases/download/" + QEMU_VERSION + "/" + QEMU_BIN_NAME + ".gz";
|
||||
return request(qemuUrl).pipe(zlib.createGunzip()).pipe(installStream).on('error', reject).on('finish', resolve);
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
copyQemu = function(context) {
|
||||
var binDir, binPath, fs, path;
|
||||
path = require('path');
|
||||
fs = require('mz/fs');
|
||||
binDir = path.join(context, '.resin');
|
||||
binPath = path.join(binDir, QEMU_BIN_NAME);
|
||||
return fs.access(binDir)["catch"]({
|
||||
code: 'ENOENT'
|
||||
}, function() {
|
||||
return fs.mkdir(binDir);
|
||||
}).then(function() {
|
||||
return getQemuPath();
|
||||
}).then(function(qemu) {
|
||||
return new Promise(function(resolve, reject) {
|
||||
var read, write;
|
||||
read = fs.createReadStream(qemu);
|
||||
write = fs.createWriteStream(binPath);
|
||||
return read.pipe(write).on('error', reject).on('finish', resolve);
|
||||
});
|
||||
}).then(function() {
|
||||
return fs.chmod(binPath, '755');
|
||||
})["return"](binPath);
|
||||
};
|
@ -1,137 +0,0 @@
|
||||
// Generated by CoffeeScript 1.12.7
|
||||
|
||||
/*
|
||||
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 Promise, getApplication;
|
||||
|
||||
Promise = require('bluebird');
|
||||
|
||||
exports.getGroupDefaults = function(group) {
|
||||
var _;
|
||||
_ = require('lodash');
|
||||
return _.chain(group).get('options').map(function(question) {
|
||||
return [question.name, question["default"]];
|
||||
}).fromPairs().value();
|
||||
};
|
||||
|
||||
exports.stateToString = function(state) {
|
||||
var _str, chalk, percentage, result;
|
||||
_str = require('underscore.string');
|
||||
chalk = require('chalk');
|
||||
percentage = _str.lpad(state.percentage, 3, '0') + '%';
|
||||
result = (chalk.blue(percentage)) + " " + (chalk.cyan(state.operation.command));
|
||||
switch (state.operation.command) {
|
||||
case 'copy':
|
||||
return result + " " + state.operation.from.path + " -> " + state.operation.to.path;
|
||||
case 'replace':
|
||||
return result + " " + state.operation.file.path + ", " + state.operation.copy + " -> " + state.operation.replace;
|
||||
case 'run-script':
|
||||
return result + " " + state.operation.script;
|
||||
default:
|
||||
throw new Error("Unsupported operation: " + state.operation.type);
|
||||
}
|
||||
};
|
||||
|
||||
exports.sudo = function(command) {
|
||||
var _, os, presidentExecuteAsync;
|
||||
_ = require('lodash');
|
||||
os = require('os');
|
||||
if (os.platform() !== 'win32') {
|
||||
console.log('If asked please type your computer password to continue');
|
||||
}
|
||||
command = _.union(_.take(process.argv, 2), command);
|
||||
presidentExecuteAsync = Promise.promisify(require('president').execute);
|
||||
return presidentExecuteAsync(command);
|
||||
};
|
||||
|
||||
exports.getManifest = function(image, deviceType) {
|
||||
var imagefs, resin, rindle;
|
||||
rindle = require('rindle');
|
||||
imagefs = require('resin-image-fs');
|
||||
resin = require('resin-sdk-preconfigured');
|
||||
return imagefs.read({
|
||||
image: image,
|
||||
partition: {
|
||||
primary: 1
|
||||
},
|
||||
path: '/device-type.json'
|
||||
}).then(rindle.extractAsync).then(JSON.parse)["catch"](function() {
|
||||
return resin.models.device.getManifestBySlug(deviceType);
|
||||
});
|
||||
};
|
||||
|
||||
exports.osProgressHandler = function(step) {
|
||||
var progressBars, rindle, visuals;
|
||||
rindle = require('rindle');
|
||||
visuals = require('resin-cli-visuals');
|
||||
step.on('stdout', process.stdout.write.bind(process.stdout));
|
||||
step.on('stderr', process.stderr.write.bind(process.stderr));
|
||||
step.on('state', function(state) {
|
||||
if (state.operation.command === 'burn') {
|
||||
return;
|
||||
}
|
||||
return console.log(exports.stateToString(state));
|
||||
});
|
||||
progressBars = {
|
||||
write: new visuals.Progress('Writing Device OS'),
|
||||
check: new visuals.Progress('Validating Device OS')
|
||||
};
|
||||
step.on('burn', function(state) {
|
||||
return progressBars[state.type].update(state);
|
||||
});
|
||||
return rindle.wait(step);
|
||||
};
|
||||
|
||||
exports.getAppInfo = function(application) {
|
||||
var _, resin;
|
||||
resin = require('resin-sdk-preconfigured');
|
||||
_ = require('lodash');
|
||||
return Promise.join(getApplication(application), resin.models.config.getDeviceTypes(), function(app, config) {
|
||||
config = _.find(config, {
|
||||
'slug': app.device_type
|
||||
});
|
||||
if (config == null) {
|
||||
throw new Error('Could not read application information!');
|
||||
}
|
||||
app.arch = config.arch;
|
||||
return app;
|
||||
});
|
||||
};
|
||||
|
||||
getApplication = function(application) {
|
||||
var match, resin;
|
||||
resin = require('resin-sdk-preconfigured');
|
||||
if ((match = /(\w+)\/(\w+)/.exec(application))) {
|
||||
return resin.models.application.getAppWithOwner(match[2], match[1]);
|
||||
}
|
||||
return resin.models.application.get(application);
|
||||
};
|
||||
|
||||
exports.getSubShellCommand = function(command) {
|
||||
var os;
|
||||
os = require('os');
|
||||
if (os.platform() === 'win32') {
|
||||
return {
|
||||
program: 'cmd.exe',
|
||||
args: ['/s', '/c', command]
|
||||
};
|
||||
} else {
|
||||
return {
|
||||
program: '/bin/sh',
|
||||
args: ['-c', command]
|
||||
};
|
||||
}
|
||||
};
|
@ -1,61 +0,0 @@
|
||||
// Generated by CoffeeScript 1.12.7
|
||||
var Logger, eol;
|
||||
|
||||
eol = require('os').EOL;
|
||||
|
||||
module.exports = Logger = (function() {
|
||||
function Logger() {
|
||||
var StreamLogger, _, colors, logger;
|
||||
StreamLogger = require('resin-stream-logger').StreamLogger;
|
||||
colors = require('colors');
|
||||
_ = require('lodash');
|
||||
logger = new StreamLogger();
|
||||
logger.addPrefix('build', colors.blue('[Build]'));
|
||||
logger.addPrefix('info', colors.cyan('[Info]'));
|
||||
logger.addPrefix('debug', colors.magenta('[Debug]'));
|
||||
logger.addPrefix('success', colors.green('[Success]'));
|
||||
logger.addPrefix('warn', colors.yellow('[Warn]'));
|
||||
logger.addPrefix('error', colors.red('[Error]'));
|
||||
this.streams = {
|
||||
build: logger.createLogStream('build'),
|
||||
info: logger.createLogStream('info'),
|
||||
debug: logger.createLogStream('debug'),
|
||||
success: logger.createLogStream('success'),
|
||||
warn: logger.createLogStream('warn'),
|
||||
error: logger.createLogStream('error')
|
||||
};
|
||||
_.mapKeys(this.streams, function(stream, key) {
|
||||
if (key !== 'debug') {
|
||||
return stream.pipe(process.stdout);
|
||||
} else {
|
||||
if (process.env.DEBUG != null) {
|
||||
return stream.pipe(process.stdout);
|
||||
}
|
||||
}
|
||||
});
|
||||
this.formatMessage = logger.formatWithPrefix.bind(logger);
|
||||
}
|
||||
|
||||
Logger.prototype.logInfo = function(msg) {
|
||||
return this.streams.info.write(msg + eol);
|
||||
};
|
||||
|
||||
Logger.prototype.logDebug = function(msg) {
|
||||
return this.streams.debug.write(msg + eol);
|
||||
};
|
||||
|
||||
Logger.prototype.logSuccess = function(msg) {
|
||||
return this.streams.success.write(msg + eol);
|
||||
};
|
||||
|
||||
Logger.prototype.logWarn = function(msg) {
|
||||
return this.streams.warn.write(msg + eol);
|
||||
};
|
||||
|
||||
Logger.prototype.logError = function(msg) {
|
||||
return this.streams.error.write(msg + eol);
|
||||
};
|
||||
|
||||
return Logger;
|
||||
|
||||
})();
|
@ -1,56 +0,0 @@
|
||||
// Generated by CoffeeScript 1.12.6
|
||||
var eol;
|
||||
|
||||
eol = require('os').EOL;
|
||||
|
||||
exports.getLogStreams = function() {
|
||||
var StreamLogger, _, colors, logger, streams;
|
||||
StreamLogger = require('resin-stream-logger').StreamLogger;
|
||||
colors = require('colors');
|
||||
_ = require('lodash');
|
||||
logger = new StreamLogger();
|
||||
logger.addPrefix('build', colors.blue('[Build]'));
|
||||
logger.addPrefix('info', colors.cyan('[Info]'));
|
||||
logger.addPrefix('debug', colors.magenta('[Debug]'));
|
||||
logger.addPrefix('success', colors.green('[Success]'));
|
||||
logger.addPrefix('warn', colors.yellow('[Warn]'));
|
||||
logger.addPrefix('error', colors.red('[Error]'));
|
||||
streams = {
|
||||
build: logger.createLogStream('build'),
|
||||
info: logger.createLogStream('info'),
|
||||
debug: logger.createLogStream('debug'),
|
||||
success: logger.createLogStream('success'),
|
||||
warn: logger.createLogStream('warn'),
|
||||
error: logger.createLogStream('error')
|
||||
};
|
||||
_.mapKeys(streams, function(stream, key) {
|
||||
if (key !== 'debug') {
|
||||
return stream.pipe(process.stdout);
|
||||
} else {
|
||||
if (process.env.DEBUG != null) {
|
||||
return stream.pipe(process.stdout);
|
||||
}
|
||||
}
|
||||
});
|
||||
return streams;
|
||||
};
|
||||
|
||||
exports.logInfo = function(logStreams, msg) {
|
||||
return logStreams.info.write(msg + eol);
|
||||
};
|
||||
|
||||
exports.logDebug = function(logStreams, msg) {
|
||||
return logStreams.debug.write(msg + eol);
|
||||
};
|
||||
|
||||
exports.logSuccess = function(logStreams, msg) {
|
||||
return logStreams.success.write(msg + eol);
|
||||
};
|
||||
|
||||
exports.logWarn = function(logStreams, msg) {
|
||||
return logStreams.warn.write(msg + eol);
|
||||
};
|
||||
|
||||
exports.logError = function(logStreams, msg) {
|
||||
return logStreams.error.write(msg + eol);
|
||||
};
|
@ -1,6 +0,0 @@
|
||||
// Generated by CoffeeScript 1.12.7
|
||||
exports.reachingOut = 'If you need help, or just want to say hi, don\'t hesitate in reaching out at:\n\n GitHub: https://github.com/resin-io/resin-cli/issues/new\n Forums: https://forums.resin.io';
|
||||
|
||||
exports.getHelp = 'If you need help, don\'t hesitate in contacting us at:\n\n GitHub: https://github.com/resin-io/resin-cli/issues/new\n Forums: https://forums.resin.io';
|
||||
|
||||
exports.resinAsciiArt = '______ _ _\n| ___ \\ (_) (_)\n| |_/ /___ ___ _ _ __ _ ___\n| // _ \\/ __| | \'_ \\ | |/ _ \\\n| |\\ \\ __/\\__ \\ | | | |_| | (_) |\n\\_| \\_\\___||___/_|_| |_(_)_|\\___/';
|
@ -1,229 +0,0 @@
|
||||
// Generated by CoffeeScript 1.12.7
|
||||
|
||||
/*
|
||||
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 Promise, _, chalk, form, messages, resin, validation, visuals,
|
||||
indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; };
|
||||
|
||||
_ = require('lodash');
|
||||
|
||||
Promise = require('bluebird');
|
||||
|
||||
form = require('resin-cli-form');
|
||||
|
||||
visuals = require('resin-cli-visuals');
|
||||
|
||||
resin = require('resin-sdk-preconfigured');
|
||||
|
||||
chalk = require('chalk');
|
||||
|
||||
validation = require('./validation');
|
||||
|
||||
messages = require('./messages');
|
||||
|
||||
exports.authenticate = function(options) {
|
||||
return form.run([
|
||||
{
|
||||
message: 'Email:',
|
||||
name: 'email',
|
||||
type: 'input',
|
||||
validate: validation.validateEmail
|
||||
}, {
|
||||
message: 'Password:',
|
||||
name: 'password',
|
||||
type: 'password'
|
||||
}
|
||||
], {
|
||||
override: options
|
||||
}).then(resin.auth.login).then(resin.auth.twoFactor.isPassed).then(function(isTwoFactorAuthPassed) {
|
||||
if (isTwoFactorAuthPassed) {
|
||||
return;
|
||||
}
|
||||
return form.ask({
|
||||
message: 'Two factor auth challenge:',
|
||||
name: 'code',
|
||||
type: 'input'
|
||||
}).then(resin.auth.twoFactor.challenge)["catch"](function(error) {
|
||||
return resin.auth.logout().then(function() {
|
||||
if (error.name === 'ResinRequestError' && error.statusCode === 401) {
|
||||
throw new Error('Invalid two factor authentication code');
|
||||
}
|
||||
throw error;
|
||||
});
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
exports.askLoginType = function() {
|
||||
return form.ask({
|
||||
message: 'How would you like to login?',
|
||||
name: 'loginType',
|
||||
type: 'list',
|
||||
choices: [
|
||||
{
|
||||
name: 'Web authorization (recommended)',
|
||||
value: 'web'
|
||||
}, {
|
||||
name: 'Credentials',
|
||||
value: 'credentials'
|
||||
}, {
|
||||
name: 'Authentication token',
|
||||
value: 'token'
|
||||
}, {
|
||||
name: 'I don\'t have a Resin account!',
|
||||
value: 'register'
|
||||
}
|
||||
]
|
||||
});
|
||||
};
|
||||
|
||||
exports.selectDeviceType = function() {
|
||||
return resin.models.device.getSupportedDeviceTypes().then(function(deviceTypes) {
|
||||
return form.ask({
|
||||
message: 'Device Type',
|
||||
type: 'list',
|
||||
choices: deviceTypes
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
exports.confirm = function(yesOption, message, yesMessage) {
|
||||
return Promise["try"](function() {
|
||||
if (yesOption) {
|
||||
if (yesMessage) {
|
||||
console.log(yesMessage);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return form.ask({
|
||||
message: message,
|
||||
type: 'confirm',
|
||||
"default": false
|
||||
});
|
||||
}).then(function(confirmed) {
|
||||
if (!confirmed) {
|
||||
throw new Error('Aborted');
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
exports.selectApplication = function(filter) {
|
||||
return resin.models.application.hasAny().then(function(hasAnyApplications) {
|
||||
if (!hasAnyApplications) {
|
||||
throw new Error('You don\'t have any applications');
|
||||
}
|
||||
return resin.models.application.getAll();
|
||||
}).filter(filter || _.constant(true)).then(function(applications) {
|
||||
return form.ask({
|
||||
message: 'Select an application',
|
||||
type: 'list',
|
||||
choices: _.map(applications, function(application) {
|
||||
return {
|
||||
name: application.app_name + " (" + application.device_type + ")",
|
||||
value: application.app_name
|
||||
};
|
||||
})
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
exports.selectOrCreateApplication = function() {
|
||||
return resin.models.application.hasAny().then(function(hasAnyApplications) {
|
||||
if (!hasAnyApplications) {
|
||||
return;
|
||||
}
|
||||
return resin.models.application.getAll().then(function(applications) {
|
||||
applications = _.map(applications, function(application) {
|
||||
return {
|
||||
name: application.app_name + " (" + application.device_type + ")",
|
||||
value: application.app_name
|
||||
};
|
||||
});
|
||||
applications.unshift({
|
||||
name: 'Create a new application',
|
||||
value: null
|
||||
});
|
||||
return form.ask({
|
||||
message: 'Select an application',
|
||||
type: 'list',
|
||||
choices: applications
|
||||
});
|
||||
});
|
||||
}).then(function(application) {
|
||||
if (application != null) {
|
||||
return application;
|
||||
}
|
||||
return form.ask({
|
||||
message: 'Choose a Name for your new application',
|
||||
type: 'input',
|
||||
validate: validation.validateApplicationName
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
exports.awaitDevice = function(uuid) {
|
||||
return resin.models.device.getName(uuid).then(function(deviceName) {
|
||||
var poll, spinner;
|
||||
spinner = new visuals.Spinner("Waiting for " + deviceName + " to come online");
|
||||
poll = function() {
|
||||
return resin.models.device.isOnline(uuid).then(function(isOnline) {
|
||||
if (isOnline) {
|
||||
spinner.stop();
|
||||
console.info("The device **" + deviceName + "** is online!");
|
||||
} else {
|
||||
spinner.start();
|
||||
return Promise.delay(3000).then(poll);
|
||||
}
|
||||
});
|
||||
};
|
||||
console.info("Waiting for " + deviceName + " to connect to resin...");
|
||||
return poll()["return"](uuid);
|
||||
});
|
||||
};
|
||||
|
||||
exports.inferOrSelectDevice = function(preferredUuid) {
|
||||
return resin.models.device.getAll().filter(function(device) {
|
||||
return device.is_online;
|
||||
}).then(function(onlineDevices) {
|
||||
if (_.isEmpty(onlineDevices)) {
|
||||
throw new Error('You don\'t have any devices online');
|
||||
}
|
||||
return form.ask({
|
||||
message: 'Select a device',
|
||||
type: 'list',
|
||||
"default": indexOf.call(_.map(onlineDevices, 'uuid'), preferredUuid) >= 0 ? preferredUuid : onlineDevices[0].uuid,
|
||||
choices: _.map(onlineDevices, function(device) {
|
||||
return {
|
||||
name: (device.name || 'Untitled') + " (" + (device.uuid.slice(0, 7)) + ")",
|
||||
value: device.uuid
|
||||
};
|
||||
})
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
exports.printErrorMessage = function(message) {
|
||||
console.error(chalk.red(message));
|
||||
return console.error(chalk.red("\n" + messages.getHelp + "\n"));
|
||||
};
|
||||
|
||||
exports.expectedError = function(message) {
|
||||
if (message instanceof Error) {
|
||||
message = message.message;
|
||||
}
|
||||
exports.printErrorMessage(message);
|
||||
return process.exit(1);
|
||||
};
|
@ -1,40 +0,0 @@
|
||||
// Generated by CoffeeScript 1.12.7
|
||||
|
||||
/*
|
||||
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 _, capitano, nplugm, patterns;
|
||||
|
||||
nplugm = require('nplugm');
|
||||
|
||||
_ = require('lodash');
|
||||
|
||||
capitano = require('capitano');
|
||||
|
||||
patterns = require('./patterns');
|
||||
|
||||
exports.register = function(regex) {
|
||||
return nplugm.list(regex).map(function(plugin) {
|
||||
var command;
|
||||
command = require(plugin);
|
||||
command.plugin = true;
|
||||
if (!_.isArray(command)) {
|
||||
return capitano.command(command);
|
||||
}
|
||||
return _.each(command, capitano.command);
|
||||
})["catch"](function(error) {
|
||||
return patterns.printErrorMessage(error.message);
|
||||
});
|
||||
};
|
@ -1,16 +0,0 @@
|
||||
// Generated by CoffeeScript 1.12.7
|
||||
exports.buffer = function(stream, bufferFile) {
|
||||
var Promise, fileWriteStream, fs;
|
||||
Promise = require('bluebird');
|
||||
fs = require('fs');
|
||||
fileWriteStream = fs.createWriteStream(bufferFile);
|
||||
return new Promise(function(resolve, reject) {
|
||||
return stream.on('error', reject).on('end', resolve).pipe(fileWriteStream);
|
||||
}).then(function() {
|
||||
return new Promise(function(resolve, reject) {
|
||||
return fs.createReadStream(bufferFile).on('open', function() {
|
||||
return resolve(this);
|
||||
}).on('error', reject);
|
||||
});
|
||||
});
|
||||
};
|
@ -1,49 +0,0 @@
|
||||
// Generated by CoffeeScript 1.12.7
|
||||
|
||||
/*
|
||||
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 isRoot, notifier, packageJSON, resinUpdateInterval, updateNotifier;
|
||||
|
||||
updateNotifier = require('update-notifier');
|
||||
|
||||
isRoot = require('is-root');
|
||||
|
||||
packageJSON = require('../../package.json');
|
||||
|
||||
resinUpdateInterval = 1000 * 60 * 60 * 24 * 1;
|
||||
|
||||
if (!isRoot()) {
|
||||
notifier = updateNotifier({
|
||||
pkg: packageJSON,
|
||||
updateCheckInterval: resinUpdateInterval
|
||||
});
|
||||
}
|
||||
|
||||
exports.hasAvailableUpdate = function() {
|
||||
return notifier != null;
|
||||
};
|
||||
|
||||
exports.notify = function() {
|
||||
if (!exports.hasAvailableUpdate()) {
|
||||
return;
|
||||
}
|
||||
notifier.notify({
|
||||
defer: false
|
||||
});
|
||||
if (notifier.update != null) {
|
||||
return console.log('Notice that you might need administrator privileges depending on your setup\n');
|
||||
}
|
||||
};
|
@ -1,41 +0,0 @@
|
||||
// Generated by CoffeeScript 1.12.7
|
||||
|
||||
/*
|
||||
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 validEmail;
|
||||
|
||||
validEmail = require('@resin.io/valid-email');
|
||||
|
||||
exports.validateEmail = function(input) {
|
||||
if (!validEmail(input)) {
|
||||
return 'Email is not valid';
|
||||
}
|
||||
return true;
|
||||
};
|
||||
|
||||
exports.validatePassword = function(input) {
|
||||
if (input.length < 8) {
|
||||
return 'Password should be 8 characters long';
|
||||
}
|
||||
return true;
|
||||
};
|
||||
|
||||
exports.validateApplicationName = function(input) {
|
||||
if (input.length < 4) {
|
||||
return 'The application name should be at least 4 characters';
|
||||
}
|
||||
return true;
|
||||
};
|
@ -26,9 +26,5 @@ gulp.task 'lint', ->
|
||||
}))
|
||||
.pipe(coffeelint.reporter())
|
||||
|
||||
gulp.task 'build', [
|
||||
'coffee'
|
||||
]
|
||||
|
||||
gulp.task 'watch', [ 'build' ], ->
|
||||
gulp.watch([ OPTIONS.files.coffee ], [ 'build' ])
|
||||
gulp.task 'watch', [ 'coffee' ], ->
|
||||
gulp.watch([ OPTIONS.files.coffee ], [ 'coffee' ])
|
||||
|
13
package.json
13
package.json
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "resin-cli",
|
||||
"version": "6.10.0",
|
||||
"version": "6.10.1",
|
||||
"description": "The official resin.io CLI tool",
|
||||
"main": "./build/actions/index.js",
|
||||
"homepage": "https://github.com/resin-io/resin-cli",
|
||||
@ -9,11 +9,17 @@
|
||||
"url": "git@github.com:resin-io/resin-cli.git"
|
||||
},
|
||||
"preferGlobal": true,
|
||||
"files": [
|
||||
"bin/",
|
||||
"build/",
|
||||
"doc/",
|
||||
"lib/"
|
||||
],
|
||||
"bin": {
|
||||
"resin": "./bin/resin"
|
||||
},
|
||||
"scripts": {
|
||||
"build": "gulp build && npm run doc",
|
||||
"build": "gulp coffee && tsc && npm run doc",
|
||||
"ci": "npm run build && catch-uncommitted",
|
||||
"doc": "mkdir -p doc/ && coffee extras/capitanodoc/index.coffee > doc/cli.markdown",
|
||||
"watch": "gulp watch",
|
||||
@ -37,7 +43,8 @@
|
||||
"gulp-coffee": "^2.2.0",
|
||||
"gulp-coffeelint": "^0.6.0",
|
||||
"gulp-shell": "^0.5.2",
|
||||
"require-npm4-to-publish": "^1.0.0"
|
||||
"require-npm4-to-publish": "^1.0.0",
|
||||
"typescript": "^2.6.1"
|
||||
},
|
||||
"dependencies": {
|
||||
"@resin.io/valid-email": "^0.1.0",
|
||||
|
16
tsconfig.json
Normal file
16
tsconfig.json
Normal file
@ -0,0 +1,16 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"module": "commonjs",
|
||||
"target": "es5",
|
||||
"outDir": "build",
|
||||
"strict": true,
|
||||
"noUnusedLocals": true,
|
||||
"noUnusedParameters": true,
|
||||
"preserveConstEnums": true,
|
||||
"removeComments": true,
|
||||
"sourceMap": true
|
||||
},
|
||||
"include": [
|
||||
"./lib/**/*.ts"
|
||||
]
|
||||
}
|
Loading…
Reference in New Issue
Block a user