mirror of
https://github.com/balena-io/etcher.git
synced 2025-07-27 13:16:36 +00:00
feat: add sudo-prompt to start on linux (#1708)
We prompt the user with a sudo-prompt upon launch on Linux-based systems to ensure the program has enough permissions for features needed throughout the program's runtime. Changelog-Entry: Add a sudo-prompt upon launch on Linux-based systems. Signed-off-by: Juan Cruz Viotti <jv@jviotti.com>
This commit is contained in:
parent
02f7a5f55b
commit
433b2734bb
@ -83,10 +83,12 @@ deb:
|
|||||||
- libxss1
|
- libxss1
|
||||||
- libxtst6
|
- libxtst6
|
||||||
- polkit-1-auth-agent | policykit-1-gnome | polkit-kde-1
|
- polkit-1-auth-agent | policykit-1-gnome | polkit-kde-1
|
||||||
|
- gksu | kdesudo
|
||||||
rpm:
|
rpm:
|
||||||
icon: assets/icon.png
|
icon: assets/icon.png
|
||||||
depends:
|
depends:
|
||||||
- lsb
|
- lsb
|
||||||
- libXScrnSaver
|
- libXScrnSaver
|
||||||
|
- beesu
|
||||||
appImage:
|
appImage:
|
||||||
icon: assets/icon.png
|
icon: assets/icon.png
|
||||||
|
@ -43,8 +43,5 @@ exports.getApplicationEntryPoint = () => {
|
|||||||
const ENTRY_POINT_ARGV_INDEX = 1
|
const ENTRY_POINT_ARGV_INDEX = 1
|
||||||
const relativeEntryPoint = electron.remote.process.argv[ENTRY_POINT_ARGV_INDEX]
|
const relativeEntryPoint = electron.remote.process.argv[ENTRY_POINT_ARGV_INDEX]
|
||||||
|
|
||||||
// On GNU/Linux, `pkexec` resolves relative paths
|
|
||||||
// from `/root`, therefore we pass an absolute path,
|
|
||||||
// in order to be on the safe side.
|
|
||||||
return path.join(CONSTANTS.PROJECT_ROOT, relativeEntryPoint)
|
return path.join(CONSTANTS.PROJECT_ROOT, relativeEntryPoint)
|
||||||
}
|
}
|
||||||
|
@ -35,6 +35,10 @@ module.exports = {
|
|||||||
flashComplete: _.template([
|
flashComplete: _.template([
|
||||||
'<%= imageBasename %> was successfully written to',
|
'<%= imageBasename %> was successfully written to',
|
||||||
'<%= drive.description %> (<%= drive.displayName %>)'
|
'<%= drive.description %> (<%= drive.displayName %>)'
|
||||||
|
].join(' ')),
|
||||||
|
|
||||||
|
providePassword: _.template([
|
||||||
|
'<%= displayName %> needs special permissions to interact with raw devices. Please provide your password.'
|
||||||
].join(' '))
|
].join(' '))
|
||||||
|
|
||||||
},
|
},
|
||||||
|
84
lib/start.js
84
lib/start.js
@ -31,5 +31,87 @@ process.env.DEBUG = `sdk:usbboot,${process.env.DEBUG}`
|
|||||||
if (process.env.ELECTRON_RUN_AS_NODE || process.env.ATOM_SHELL_INTERNAL_RUN_AS_NODE) {
|
if (process.env.ELECTRON_RUN_AS_NODE || process.env.ATOM_SHELL_INTERNAL_RUN_AS_NODE) {
|
||||||
require('./cli/etcher')
|
require('./cli/etcher')
|
||||||
} else {
|
} else {
|
||||||
require('./gui/etcher')
|
const electron = require('electron')
|
||||||
|
const os = require('os')
|
||||||
|
const _ = require('lodash')
|
||||||
|
const Bluebird = require('bluebird')
|
||||||
|
const commandExists = Bluebird.promisify(require('command-exists'))
|
||||||
|
const childProcess = require('child_process')
|
||||||
|
const permissions = require('./shared/permissions')
|
||||||
|
const errors = require('./shared/errors')
|
||||||
|
const EXIT_CODES = require('./shared/exit-codes')
|
||||||
|
const packageJSON = require('../package.json')
|
||||||
|
const messages = require('./shared/messages')
|
||||||
|
|
||||||
|
const MESSAGE = messages.info.providePassword({
|
||||||
|
displayName: packageJSON.displayName
|
||||||
|
})
|
||||||
|
|
||||||
|
const ELEVATOR_COMMANDS = [
|
||||||
|
{
|
||||||
|
name: 'gksudo',
|
||||||
|
options: [ '--preserve-env', '--message', MESSAGE ]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'kdesudo',
|
||||||
|
options: [ '--comment', MESSAGE, '--' ]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'beesu',
|
||||||
|
options: [ '--preserve-environment' ]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
|
permissions.isElevated().then((isElevated) => {
|
||||||
|
if (_.includes([ 'win32', 'darwin' ], os.platform()) || isElevated) {
|
||||||
|
require('./gui/etcher')
|
||||||
|
return Bluebird.resolve()
|
||||||
|
}
|
||||||
|
|
||||||
|
return Bluebird.any(_.map(ELEVATOR_COMMANDS, (command) => {
|
||||||
|
return commandExists(command.name).then((exists) => {
|
||||||
|
if (!exists) {
|
||||||
|
throw new Error(`Command does not exist: ${command.name}`)
|
||||||
|
}
|
||||||
|
|
||||||
|
return command
|
||||||
|
})
|
||||||
|
})).then((command) => {
|
||||||
|
return new Bluebird((resolve, reject) => {
|
||||||
|
const argv = process.env.APPIMAGE ? [ process.env.APPIMAGE ] : process.argv
|
||||||
|
const options = command.options.concat([ 'env', 'SKIP=1' ]).concat(argv)
|
||||||
|
|
||||||
|
console.log(`Running ${command.name}`)
|
||||||
|
|
||||||
|
const child = childProcess.spawn(command.name, options, {
|
||||||
|
detached: true,
|
||||||
|
env: process.env
|
||||||
|
})
|
||||||
|
|
||||||
|
child.stdout.on('data', (data) => {
|
||||||
|
console.log(data.toString())
|
||||||
|
})
|
||||||
|
|
||||||
|
child.stderr.on('data', (data) => {
|
||||||
|
console.error(data.toString())
|
||||||
|
})
|
||||||
|
|
||||||
|
child.on('exit', () => {
|
||||||
|
electron.app.quit()
|
||||||
|
})
|
||||||
|
|
||||||
|
child.on('error', reject)
|
||||||
|
})
|
||||||
|
}).catch(Bluebird.AggregateError, () => {
|
||||||
|
const commands = _.map(ELEVATOR_COMMANDS, 'name')
|
||||||
|
const formattedCommands = `${_.initial(commands).join(', ')}, or ${_.last(commands)}`
|
||||||
|
throw errors.createUserError({
|
||||||
|
title: 'Can\'t elevate the application',
|
||||||
|
description: `Please ensure you have either ${formattedCommands} available in your system`
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}).catch((error) => {
|
||||||
|
electron.dialog.showErrorBox(errors.getTitle(error), errors.getDescription(error))
|
||||||
|
electron.app.exit(EXIT_CODES.GENERAL_ERROR)
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
9
npm-shrinkwrap.json
generated
9
npm-shrinkwrap.json
generated
@ -38,9 +38,9 @@
|
|||||||
"resolved": "https://registry.npmjs.org/@types/lodash.some/-/lodash.some-4.6.2.tgz"
|
"resolved": "https://registry.npmjs.org/@types/lodash.some/-/lodash.some-4.6.2.tgz"
|
||||||
},
|
},
|
||||||
"@types/node": {
|
"@types/node": {
|
||||||
"version": "7.0.44",
|
"version": "7.0.46",
|
||||||
"from": "@types/node@>=7.0.18 <8.0.0",
|
"from": "@types/node@>=7.0.18 <8.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-7.0.44.tgz",
|
"resolved": "https://registry.npmjs.org/@types/node/-/node-7.0.46.tgz",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"@types/react": {
|
"@types/react": {
|
||||||
@ -855,6 +855,11 @@
|
|||||||
"resolved": "http://registry.npmjs.org/combined-stream/-/combined-stream-0.0.7.tgz",
|
"resolved": "http://registry.npmjs.org/combined-stream/-/combined-stream-0.0.7.tgz",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"command-exists": {
|
||||||
|
"version": "1.2.2",
|
||||||
|
"from": "command-exists@latest",
|
||||||
|
"resolved": "https://registry.npmjs.org/command-exists/-/command-exists-1.2.2.tgz"
|
||||||
|
},
|
||||||
"command-join": {
|
"command-join": {
|
||||||
"version": "2.0.0",
|
"version": "2.0.0",
|
||||||
"from": "command-join@2.0.0",
|
"from": "command-join@2.0.0",
|
||||||
|
@ -50,6 +50,7 @@
|
|||||||
"bluebird": "3.4.1",
|
"bluebird": "3.4.1",
|
||||||
"bootstrap-sass": "3.3.6",
|
"bootstrap-sass": "3.3.6",
|
||||||
"chalk": "1.1.3",
|
"chalk": "1.1.3",
|
||||||
|
"command-exists": "1.2.2",
|
||||||
"command-join": "2.0.0",
|
"command-join": "2.0.0",
|
||||||
"debug": "2.6.0",
|
"debug": "2.6.0",
|
||||||
"drivelist": "5.2.4",
|
"drivelist": "5.2.4",
|
||||||
|
Loading…
x
Reference in New Issue
Block a user