Require superuser for scan commands, also introduce docker timeout

This commit is contained in:
Kostas Lekkas 2017-03-10 15:11:27 +00:00
parent 08db3ace03
commit 73dd625ede
No known key found for this signature in database
GPG Key ID: 7742375E5EDF01C3
2 changed files with 68 additions and 66 deletions

View File

@ -4,76 +4,75 @@ Docker = require('docker-toolbelt')
form = require('resin-cli-form')
chalk = require('chalk')
filterOutSupervisorContainer = (container) ->
exports.dockerPort = dockerPort = 2375
exports.dockerTimeout = dockerTimeout = 2000
exports.filterOutSupervisorContainer = filterOutSupervisorContainer = (container) ->
for name in container.Names
return false if name.includes('resin_supervisor')
return true
module.exports =
exports.selectContainerFromDevice = Promise.method (deviceIp, filterSupervisor = false) ->
docker = new Docker(host: deviceIp, port: dockerPort, timeout: dockerTimeout)
filterOutSupervisorContainer: filterOutSupervisorContainer
# List all containers, including those not running
docker.listContainersAsync(all: true)
.filter (container) ->
return true if not filterSupervisor
filterOutSupervisorContainer(container)
.then (containers) ->
if _.isEmpty(containers)
throw new Error("No containers found in #{deviceIp}")
selectContainerFromDevice: Promise.method (deviceIp, filterSupervisor = false) ->
docker = new Docker(host: deviceIp, port: 2375)
return form.ask
message: 'Select a container'
type: 'list'
choices: _.map containers, (container) ->
containerName = container.Names[0] or 'Untitled'
shortContainerId = ('' + container.Id).substr(0, 11)
containerStatus = container.Status
# List all containers, including those not running
docker.listContainersAsync(all: true)
.filter (container) ->
return true if not filterSupervisor
filterOutSupervisorContainer(container)
.then (containers) ->
if _.isEmpty(containers)
throw new Error("No containers found in #{deviceIp}")
return {
name: "#{containerName} (#{shortContainerId}) - #{containerStatus}"
value: container.Id
}
return form.ask
message: 'Select a container'
type: 'list'
choices: _.map containers, (container) ->
containerName = container.Names[0] or 'Untitled'
shortContainerId = ('' + container.Id).substr(0, 11)
containerStatus = container.Status
exports.pipeContainerStream = Promise.method ({ deviceIp, name, outStream, follow = false }) ->
docker = new Docker(host: deviceIp, port: dockerPort)
return {
name: "#{containerName} (#{shortContainerId}) - #{containerStatus}"
value: container.Id
}
container = docker.getContainer(name)
container.inspectAsync()
.then (containerInfo) ->
return containerInfo?.State?.Running
.then (isRunning) ->
container.attachAsync
logs: not follow or not isRunning
stream: follow and isRunning
stdout: true
stderr: true
.then (containerStream) ->
containerStream.pipe(outStream)
.catch (err) ->
err = '' + err.statusCode
if err is '404'
return console.log(chalk.red.bold("Container '#{name}' not found."))
throw err
pipeContainerStream: Promise.method ({ deviceIp, name, outStream, follow = false }) ->
docker = new Docker(host: deviceIp, port: 2375)
# A function to reliably execute a command
# in all supported operating systems, including
# different Windows environments like `cmd.exe`
# and `Cygwin` should be encapsulated in a
# re-usable package.
exports.getSubShellCommand = (command) ->
os = require('os')
container = docker.getContainer(name)
container.inspectAsync()
.then (containerInfo) ->
return containerInfo?.State?.Running
.then (isRunning) ->
container.attachAsync
logs: not follow or not isRunning
stream: follow and isRunning
stdout: true
stderr: true
.then (containerStream) ->
containerStream.pipe(outStream)
.catch (err) ->
err = '' + err.statusCode
if err is '404'
return console.log(chalk.red.bold("Container '#{name}' not found."))
throw err
# A function to reliably execute a command
# in all supported operating systems, including
# different Windows environments like `cmd.exe`
# and `Cygwin` should be encapsulated in a
# re-usable package.
getSubShellCommand: (command) ->
os = require('os')
if os.platform() is 'win32'
return {
program: 'cmd.exe'
args: [ '/s', '/c', command ]
}
else
return {
program: '/bin/sh'
args: [ '-c', command ]
}
if os.platform() is 'win32'
return {
program: 'cmd.exe'
args: [ '/s', '/c', command ]
}
else
return {
program: '/bin/sh'
args: [ '-c', command ]
}

View File

@ -14,7 +14,6 @@ See the License for the specific language governing permissions and
limitations under the License.
###
dockerInfoProperties = [
'Containers'
'ContainersRunning'
@ -64,6 +63,7 @@ module.exports =
Docker = require('docker-toolbelt')
{ discover } = require('resin-sync')
{ SpinnerPromise } = require('resin-cli-visuals')
{ dockerPort, dockerTimeout } = require('./common')
if options.timeout?
options.timeout *= 1000
@ -74,13 +74,16 @@ module.exports =
startMessage: 'Scanning for local resinOS devices..'
stopMessage: 'Reporting scan results'
.filter ({ address }) ->
docker = new Docker(host: address, port: 2375)
docker.infoAsync().return(true).catchReturn(false)
Promise.try ->
docker = new Docker(host: address, port: dockerPort, timeout: dockerTimeout)
docker.pingAsync()
.return(true)
.catchReturn(false)
.tap (devices) ->
if _.isEmpty(devices)
throw new Error('Could not find any resinOS devices in the local network')
.map ({ host, address }) ->
docker = new Docker(host: address, port: 2375)
docker = new Docker(host: address, port: dockerPort, timeout: dockerTimeout)
Promise.props
dockerInfo: docker.infoAsync().catchReturn('Could not get Docker info')
dockerVersion: docker.versionAsync().catchReturn('Could not get Docker version')