mirror of
https://github.com/balena-io/balena-cli.git
synced 2024-12-21 22:47:48 +00:00
Call os initialize as an elevated process
Currently, the fact that `os initialize` requires elevated permissions forced us to require calling commands that reuse it, such as `device init` and `quickstart` with administrator permissions as well. This ended up causing issues like saving images in the cache that belong to root, or initializing git repositories that requires `sudo` to commit. The solution is to call `os initialize` as a child process preppending `sudo` within `device init`. Fixes: https://github.com/resin-io/resin-cli/issues/109
This commit is contained in:
parent
ed6427c541
commit
445e37ccaf
@ -1,5 +1,5 @@
|
|||||||
(function() {
|
(function() {
|
||||||
var Promise, _, capitano, commandOptions, events, form, patterns, resin, rimraf, tmp, visuals;
|
var Promise, _, capitano, commandOptions, events, form, helpers, patterns, resin, rimraf, tmp, visuals;
|
||||||
|
|
||||||
Promise = require('bluebird');
|
Promise = require('bluebird');
|
||||||
|
|
||||||
@ -19,6 +19,8 @@
|
|||||||
|
|
||||||
patterns = require('../utils/patterns');
|
patterns = require('../utils/patterns');
|
||||||
|
|
||||||
|
helpers = require('../utils/helpers');
|
||||||
|
|
||||||
tmp = Promise.promisifyAll(require('tmp'));
|
tmp = Promise.promisifyAll(require('tmp'));
|
||||||
|
|
||||||
tmp.setGracefulCleanup();
|
tmp.setGracefulCleanup();
|
||||||
@ -131,7 +133,6 @@
|
|||||||
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',
|
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],
|
options: [commandOptions.optionalApplication, commandOptions.yes],
|
||||||
permission: 'user',
|
permission: 'user',
|
||||||
root: true,
|
|
||||||
action: function(params, options, done) {
|
action: function(params, options, done) {
|
||||||
return Promise["try"](function() {
|
return Promise["try"](function() {
|
||||||
if (options.application != null) {
|
if (options.application != null) {
|
||||||
@ -148,7 +149,7 @@
|
|||||||
return Promise.using(download(), function(temporalPath) {
|
return Promise.using(download(), function(temporalPath) {
|
||||||
return capitano.runAsync("device register " + application.app_name).then(resin.models.device.get).tap(function(device) {
|
return capitano.runAsync("device register " + application.app_name).then(resin.models.device.get).tap(function(device) {
|
||||||
return capitano.runAsync("os configure " + temporalPath + " " + device.uuid).then(function() {
|
return capitano.runAsync("os configure " + temporalPath + " " + device.uuid).then(function() {
|
||||||
return capitano.runAsync("os initialize " + temporalPath + " " + application.device_type);
|
return helpers.sudo(['os', 'initialize', temporalPath, application.device_type]);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}).then(function(device) {
|
}).then(function(device) {
|
||||||
|
@ -102,6 +102,7 @@
|
|||||||
description: 'initialize an os image',
|
description: 'initialize an os image',
|
||||||
help: 'Use this command to initialize a previously configured operating system image.\n\nExamples:\n\n $ resin os initialize ../path/rpi.img \'raspberry-pi\'',
|
help: 'Use this command to initialize a previously configured operating system image.\n\nExamples:\n\n $ resin os initialize ../path/rpi.img \'raspberry-pi\'',
|
||||||
permission: 'user',
|
permission: 'user',
|
||||||
|
root: true,
|
||||||
action: function(params, options, done) {
|
action: function(params, options, done) {
|
||||||
console.info('Initializing device');
|
console.info('Initializing device');
|
||||||
return resin.models.device.getManifestBySlug(params.type).then(function(manifest) {
|
return resin.models.device.getManifestBySlug(params.type).then(function(manifest) {
|
||||||
|
@ -17,7 +17,6 @@
|
|||||||
signature: 'quickstart [name]',
|
signature: 'quickstart [name]',
|
||||||
description: 'getting started with resin.io',
|
description: 'getting started with resin.io',
|
||||||
help: 'Use this command to run a friendly wizard to get started with resin.io.\n\nThe wizard will guide you through:\n\n - Create an application.\n - Initialise an SDCard with the resin.io operating system.\n - Associate an existing project directory with your resin.io application.\n - Push your project to your devices.\n\nExamples:\n\n $ sudo resin quickstart\n $ sudo resin quickstart MyApp',
|
help: 'Use this command to run a friendly wizard to get started with resin.io.\n\nThe wizard will guide you through:\n\n - Create an application.\n - Initialise an SDCard with the resin.io operating system.\n - Associate an existing project directory with your resin.io application.\n - Push your project to your devices.\n\nExamples:\n\n $ sudo resin quickstart\n $ sudo resin quickstart MyApp',
|
||||||
root: true,
|
|
||||||
permission: 'user',
|
permission: 'user',
|
||||||
action: function(params, options, done) {
|
action: function(params, options, done) {
|
||||||
return Promise["try"](function() {
|
return Promise["try"](function() {
|
||||||
|
@ -1,12 +1,16 @@
|
|||||||
(function() {
|
(function() {
|
||||||
var Promise, _, chalk, os;
|
var Promise, _, capitano, chalk, child_process, os;
|
||||||
|
|
||||||
Promise = require('bluebird');
|
Promise = require('bluebird');
|
||||||
|
|
||||||
|
capitano = Promise.promisifyAll(require('capitano'));
|
||||||
|
|
||||||
_ = require('lodash');
|
_ = require('lodash');
|
||||||
|
|
||||||
_.str = require('underscore.string');
|
_.str = require('underscore.string');
|
||||||
|
|
||||||
|
child_process = require('child_process');
|
||||||
|
|
||||||
os = require('os');
|
os = require('os');
|
||||||
|
|
||||||
chalk = require('chalk');
|
chalk = require('chalk');
|
||||||
@ -44,4 +48,16 @@
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
exports.sudo = function(command) {
|
||||||
|
var spawn;
|
||||||
|
if (os.platform() === 'win32') {
|
||||||
|
return capitano.runAsync(command.join(' '));
|
||||||
|
}
|
||||||
|
command = _.union(_.take(process.argv, 2), command);
|
||||||
|
spawn = child_process.spawn('sudo', command, {
|
||||||
|
stdio: 'inherit'
|
||||||
|
});
|
||||||
|
return exports.waitStream(spawn);
|
||||||
|
};
|
||||||
|
|
||||||
}).call(this);
|
}).call(this);
|
||||||
|
@ -7,6 +7,7 @@ form = require('resin-cli-form')
|
|||||||
events = require('resin-cli-events')
|
events = require('resin-cli-events')
|
||||||
rimraf = Promise.promisify(require('rimraf'))
|
rimraf = Promise.promisify(require('rimraf'))
|
||||||
patterns = require('../utils/patterns')
|
patterns = require('../utils/patterns')
|
||||||
|
helpers = require('../utils/helpers')
|
||||||
tmp = Promise.promisifyAll(require('tmp'))
|
tmp = Promise.promisifyAll(require('tmp'))
|
||||||
tmp.setGracefulCleanup()
|
tmp.setGracefulCleanup()
|
||||||
|
|
||||||
@ -188,7 +189,6 @@ exports.init =
|
|||||||
commandOptions.yes
|
commandOptions.yes
|
||||||
]
|
]
|
||||||
permission: 'user'
|
permission: 'user'
|
||||||
root: true
|
|
||||||
action: (params, options, done) ->
|
action: (params, options, done) ->
|
||||||
Promise.try ->
|
Promise.try ->
|
||||||
return options.application if options.application?
|
return options.application if options.application?
|
||||||
@ -206,7 +206,7 @@ exports.init =
|
|||||||
.then(resin.models.device.get)
|
.then(resin.models.device.get)
|
||||||
.tap (device) ->
|
.tap (device) ->
|
||||||
capitano.runAsync("os configure #{temporalPath} #{device.uuid}").then ->
|
capitano.runAsync("os configure #{temporalPath} #{device.uuid}").then ->
|
||||||
capitano.runAsync("os initialize #{temporalPath} #{application.device_type}")
|
helpers.sudo([ 'os', 'initialize', temporalPath, application.device_type ])
|
||||||
.then (device) ->
|
.then (device) ->
|
||||||
console.log('Done')
|
console.log('Done')
|
||||||
return device.uuid
|
return device.uuid
|
||||||
|
@ -105,6 +105,7 @@ exports.initialize =
|
|||||||
$ resin os initialize ../path/rpi.img 'raspberry-pi'
|
$ resin os initialize ../path/rpi.img 'raspberry-pi'
|
||||||
'''
|
'''
|
||||||
permission: 'user'
|
permission: 'user'
|
||||||
|
root: true
|
||||||
action: (params, options, done) ->
|
action: (params, options, done) ->
|
||||||
console.info('Initializing device')
|
console.info('Initializing device')
|
||||||
resin.models.device.getManifestBySlug(params.type)
|
resin.models.device.getManifestBySlug(params.type)
|
||||||
|
@ -23,7 +23,6 @@ exports.wizard =
|
|||||||
$ sudo resin quickstart
|
$ sudo resin quickstart
|
||||||
$ sudo resin quickstart MyApp
|
$ sudo resin quickstart MyApp
|
||||||
'''
|
'''
|
||||||
root: true
|
|
||||||
permission: 'user'
|
permission: 'user'
|
||||||
action: (params, options, done) ->
|
action: (params, options, done) ->
|
||||||
Promise.try ->
|
Promise.try ->
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
Promise = require('bluebird')
|
Promise = require('bluebird')
|
||||||
|
capitano = Promise.promisifyAll(require('capitano'))
|
||||||
_ = require('lodash')
|
_ = require('lodash')
|
||||||
_.str = require('underscore.string')
|
_.str = require('underscore.string')
|
||||||
|
child_process = require('child_process')
|
||||||
os = require('os')
|
os = require('os')
|
||||||
chalk = require('chalk')
|
chalk = require('chalk')
|
||||||
|
|
||||||
@ -28,3 +30,17 @@ exports.waitStream = (stream) ->
|
|||||||
stream.on('close', resolve)
|
stream.on('close', resolve)
|
||||||
stream.on('end', resolve)
|
stream.on('end', resolve)
|
||||||
stream.on('error', reject)
|
stream.on('error', reject)
|
||||||
|
|
||||||
|
exports.sudo = (command) ->
|
||||||
|
|
||||||
|
# Bypass privilege elevation for Windows for now.
|
||||||
|
# We should use `windosu` in this case.
|
||||||
|
if os.platform() is 'win32'
|
||||||
|
return capitano.runAsync(command.join(' '))
|
||||||
|
|
||||||
|
command = _.union(_.take(process.argv, 2), command)
|
||||||
|
|
||||||
|
spawn = child_process.spawn 'sudo', command,
|
||||||
|
stdio: 'inherit'
|
||||||
|
|
||||||
|
return exports.waitStream(spawn)
|
||||||
|
Loading…
Reference in New Issue
Block a user