Files
RootPanel/core/interface/Node.coffee
2015-02-07 04:09:16 +08:00

180 lines
4.1 KiB
CoffeeScript

SSHConnection = require 'ssh2'
{_, child_process, async, fs} = app.libs
{config, logger} = app
{available_plugins} = config.plugin
if fs.existsSync config.ssh.id_key
id_key = fs.readFileSync config.ssh.id_key
module.exports = class Node
name: ''
master: false
available_components: []
constructor: (info) ->
_.extend @, info
for component_type in @available_components
unless component_type in available_plugins
err = new Error "Node:#{@name} include unknown Component:#{component_type}"
logger.fatal err
throw err
# @param callback(err, stdout, stderr)
runCommand: (command, callback) ->
unless @master
return @runCommandRemote command, callback
child_process.exec command, (err, stdout, stderr) ->
callback err, stdout, stderr
# @param options: args, stdin
# @param callback(err, stdout, stderr)
exec: (command, options, callback) ->
{args, stdin} = options
args ?= []
stdout = ''
stderr = ''
error = null
proc = child_process.spawn command, args
if stdin
proc.stdin.end stdin
proc.on 'error', (err) ->
error = err
proc.stdout.on 'data', (data) ->
stdout += data
proc.stderr.on 'data', (data) ->
stderr += data
proc.on 'exit', ->
callback error, stdout, stderr
# @param options: mode, owner
writeFile: (filename, body, options, callback) ->
unless @master
return @writeFileRemote filename, body, options, callback
{mode, owner} = options
async.auto
touch: (callback) ->
child_process.exec "sudo touch #{filename}", (err) ->
callback err
chmod: ['touch', (callback) ->
unless mode
return callback()
child_process.exec "sudo chmod #{mode} #{filename}", (err) ->
callback err
]
chown: ['touch', (callback) ->
unless owner
return callback()
child_process.exec "sudo chown #{owner}:#{owner} #{filename}", (err) ->
callback err
]
tee: ['chmod', 'chown', (callback) =>
@exec 'sudo',
args: ['tee', filename]
stdin: body
, callback
]
, callback
# @param callback(err, body)
readFile: (filename, callback) ->
unless @master
return @readFileRemote filename, callback
@runCommand "sudo cat #{filename}", (err, stdout) ->
callback err, stdout
connectRemote: (callback) ->
connection = new SSHConnection()
connection.on 'ready', ->
callback connection
connection.connect
host: @host
username: 'rpadmin'
privateKey: id_key
runCommandRemote: (command, callback) ->
@execRemote command, {}, callback
execRemote: (command, options, callback) ->
{args, stdin} = options
args ?= []
command = "#{command} #{args.join(' ')}"
stdout = ''
stderr = ''
@connectRemote (connection) ->
connection.exec command, (err, stream) ->
return callback err if err
if stdin
stream.end stdin
stream.on 'data', (data) ->
stdout += data
stream.stderr.on 'data', (data) ->
stderr += data.toString()
stream.on 'close', ->
connection.end()
callback err, stdout, stderr
writeFileRemote: (filename, body, options, callback) ->
{mode, owner} = options
async.auto
touch: (callback) =>
@runCommandRemote "sudo touch #{filename}", (err) ->
callback err
chmod: ['touch', (callback) =>
unless mode
return callback()
@runCommandRemote "sudo chmod #{mode} #{filename}", (err) ->
callback err
]
chown: ['touch', (callback) =>
unless owner
return callback()
@runCommandRemote "sudo chown #{owner}:#{owner} #{filename}", (err) ->
callback err
]
tee: ['chmod', 'chown', (callback) =>
@execRemote 'sudo',
args: ['tee', filename]
stdin: body
, callback
]
, callback
readFileRemote: (filename, callback) ->
@runCommandRemote "sudo cat #{filename}", (err, stdout) ->
callback err, stdout