import * as child_process from 'promisify-child-process' import * as util from 'util' import { renderFile as renderFileSync } from 'twig' import * as path from 'path' import { HOSTS } from './config' const renderFile: any = util.promisify(renderFileSync); export async function sshCommand(host: string, cmd: string[]) { console.log(`[${host}] $ ${cmd.join(' ')}`) return await child_process.spawn('ssh', [host, ...cmd], {encoding: 'utf8'}) } async function sshCreateFile(host: string, path: string, content: string) { const ps = child_process.spawn('ssh', [host, 'sh', '-c', `cat > ${path}`]) ps.stdin.end(content, 'utf-8') return await ps } async function uberspaceOpenPort(host: string): Promise { const res = await sshCommand(host, ['uberspace', 'port', 'add'],) const p = (res.stdout as string).match(/Port (\d+) will/) if(!p) { throw new Error('could not open port.\n'+res.stdout+res.stderr) } return parseInt(p[1]) } async function setupHost(host: string) { try { await sshCommand(host, ['mkdir', '-p', '~/configs', '~/databases']) const version = '1.3.4' const url = `https://github.com/mumble-voip/mumble/releases/download/${version}/murmur-static_x86-${version}.tar.bz2` await sshCommand(host, ['sh', '-c', `cd ~/tmp && wget ${url} && tar xvjf murmur-static_x86-${version}.tar.bz2 && mv murmur-static_x86-${version} ~/mumble`]) } catch(err) { console.log(err) } } export async function createInstance(hostname: string, uuid: string, serverPassword: string, suPassword: string): Promise { const { sshString } = HOSTS.find(h => h.hostname == hostname) try { const port = await uberspaceOpenPort(sshString) await sshCreateFile( sshString, `~/configs/${uuid}.ini`, await renderFile(path.join(__dirname, 'templates/murmur.ini'), { user: sshString.split('@')[0], serverpassword: serverPassword, hostname, port, uuid, }) ) await sshCreateFile( sshString, `~/etc/services.d/murmur-${uuid}.ini`, await renderFile(path.join(__dirname, 'templates/service.ini'), { uuid }) ) await sshCommand(sshString, ['~/mumble/murmur.x86', '-fg', '-ini', `~/configs/${uuid}.ini`, '-supw', suPassword]) await sshCommand(sshString, ['supervisorctl', 'update']) return port } catch(err) { console.log(err) throw err } } export async function removeInstance(sshString: string, uuid: string, port: number) { const service = 'murmur-'+uuid const res = await sshCommand(sshString, [ 'supervisorctl', 'stop', service, ';', 'supervisorctl', 'remove', service, ';', 'rm', `~/etc/services.d/${service}.ini`, `~/databases/${uuid}.db`, `~/configs/${uuid}.ini`, ';', 'uberspace', 'port', 'del', port.toString(), '||', 'true' ]) console.log(res) }