maestro/app/classes/metal/RemoteHost.js
2020-02-21 00:36:55 -06:00

78 lines
2.4 KiB
JavaScript

const Host = require('./Host')
const ssh = require('ssh2')
const ExecutionResult = require('../logical/ExecutionResult')
const fs = require('fs').promises
class RemoteHost extends Host {
_ssh = false
async execute(command) {
const conn = await this._get_ssh_connection()
const result = new ExecutionResult()
await new Promise((resolve, reject) => {
conn.exec(command, (error, stream) => {
if ( error ) reject(error)
else {
stream.on('close', (code, signal) => {
result.exit(code)
resolve()
}).on('data', (data) => {
result.out(data)
}).stderr.on('data', (data) => {
result.error(data)
})
}
})
})
return result
}
async open_file_read_stream(file_path) {
file_path = typeof file_path === 'string' ? file_path : file_path.path
const sftp = await this._get_sftp_connection()
return sftp.createReadStream(file_path)
}
async open_file_write_stream(file_path) {
file_path = typeof file_path === 'string' ? file_path : file_path.path
const sftp = await this._get_sftp_connection()
return sftp.createWriteStream(file_path)
}
async _get_ssh_connection() {
if ( this._ssh ) return this._ssh
if ( this.config.ssh_params && this.config.ssh_params.key_file && !this.config.ssh_params.privateKey ) {
this.config.ssh_params.privateKey = await fs.readFile(this.config.ssh_params.key_file)
}
return new Promise((resolve, reject) => {
const client = new ssh.Client()
client.on('ready', () => {
this._ssh = client
resolve(client)
}).connect(this.config.ssh_params)
client.on('error', reject)
})
}
async _get_sftp_connection() {
const ssh = await this._get_ssh_connection()
return new Promise((resolve, reject) => {
ssh.sftp((err, sftp) => {
if ( err ) reject(err)
else resolve(sftp)
})
})
}
async _cleanup() {
if ( this._ssh ) {
this._ssh.end()
}
}
}
module.exports = exports = RemoteHost