/* global __appdir */ var path = require('path') var shell = require('shelljs') // var child = require('child_process') var ipxeGIT = 'git://git.ipxe.org/ipxe.git' var io = require(path.join(__appdir, 'lib', 'socketio')) const fs = require('fs') // Only one building process per version at a time. var building = { efi: false, bios: false } var make = {} module.exports = { buildIpxe: async function (req, res) { const ipxeVersion = req.params.version // Different make commands for efi / bios are needed. var makeCmd = '' // Only one building process can be running. if (!building[ipxeVersion]) { makeCmd = 'make bin-x86_64-efi/snponly.efi EMBED=' + path.join(__appdir, 'ipxe', 'embedded_' + ipxeVersion + '.ipxe') + ' TRUST=' + path.join(__appdir, 'bin', 'fullchain.pem')// + ' bin/undionly.kpxe' updateInProgress(ipxeVersion, true) } else { res.send({ status: 'ALREADY_BUILDING', error: 'Building ' + ipxeVersion + '-iPXE is already in progress.' }) return } // Sending feedback, that the ipxe building progress started. res.status(200).send({ status: 'SUCCESS', msg: 'Starting iPXE building process' }) // Cloning git. sendToLog(ipxeVersion, 'Cloning git ...\n', 'primary') await cloneIpxe(ipxeVersion) // Copying configs. sendToLog(ipxeVersion, 'Copying configs ...\n', 'primary') copyConfigs(ipxeVersion) // Make ipxe. sendToLog(ipxeVersion, 'Make iPXE ...\n', 'primary') shell.cd(path.join(__appdir, 'ipxe', 'ipxe_' + ipxeVersion, 'src')) await new Promise((resolve, reject) => { make[ipxeVersion] = shell.exec(makeCmd, { async: true }, () => { // make[ipxeVersion] = child.exec(makeCmd, { async: true }, () => { updateInProgress(ipxeVersion, false) resolve() }) // Send the output to the frontend log. make[ipxeVersion].stdout.on('data', data => { sendToLog(ipxeVersion, data, 'normal') }) make[ipxeVersion].stderr.on('data', data => { sendToLog(ipxeVersion, data, 'error') }) }) // Copy and rename the ipxe file. shell.cp('bin/undionly.kpxe', path.join(__appdir, 'ipxe')) shell.mv(path.join(__appdir, 'ipxe', 'undionly.kpxe'), path.join(__appdir, 'ipxe', 'ipxe.' + ipxeVersion)) }, stopBuilding: async function (req, res) { // TODO: KILLING IS NOT WORKING.. fml const process = make[req.params.version] console.log(process) if (process) { console.log('KILLING IT °_°') // process.stdin.pause() // shell.kill(process.pid, 'SIGINT') // const kill = 'kill -2 ' + process.pid // console.log(kill) // shell.exec(kill) // process.kill("SIGINT") // child.exec("kill -2 " + process.pid) } res.send({ status: 'SUCCESS', data: process }) }, clean: async function (req, res) { const ipxeVersion = req.params.version if (building[ipxeVersion]) { res.send({ status: 'ALREADY_BUILDING', error: 'Can\'t clean, while building' + ipxeVersion + '-iPXE is in progress.' }) return } else { updateInProgress(ipxeVersion, true) res.send({ status: 'SUCCESS', msg: 'Cleaning iPXE started' }) } shell.cd(path.join(__appdir, 'ipxe')) shell.rm('-rf', 'ipxe_' + ipxeVersion) shell.rm(path.join(__appdir, 'ipxe', 'ipxe.' + ipxeVersion)) shell.rm(path.join(__appdir, 'ipxe', 'log_' + ipxeVersion + '.txt')) updateInProgress(ipxeVersion, false) sendToLog(ipxeVersion, 'iPXE files successfully cleaned', 'success', false) }, status: function (ipxeVersion) { return building[ipxeVersion] } } async function cloneIpxe (ipxeVersion) { // Check if git is installed on the server. if (!shell.which('git')) { return { status: 'GIT_MISSING', error: 'Please install git on the server.' } } shell.cd(path.join(__appdir, 'ipxe')) return new Promise((resolve, reject) => { var clone = shell.exec('git clone ' + ipxeGIT + ' ipxe_' + ipxeVersion, { async: true }, () => { resolve() }) clone.stdout.on('data', data => { sendToLog(ipxeVersion, data, 'normal') }) clone.stderr.on('data', data => { sendToLog(ipxeVersion, data, 'error') }) }) } function copyConfigs (ipxeVersion) { // Remove the default configs and paste in the customized ones. shell.rm(path.join(__appdir, 'ipxe', 'ipxe_' + ipxeVersion, 'src', 'config', 'general.h')) shell.rm(path.join(__appdir, 'ipxe', 'ipxe_' + ipxeVersion, 'src', 'config', 'console.h')) shell.cp(path.join(__appdir, 'ipxe', 'general_' + ipxeVersion + '.h'), path.join(__appdir, 'ipxe', 'ipxe_' + ipxeVersion, 'src', 'config', 'general.h')) shell.cp(path.join(__appdir, 'ipxe', 'console_' + ipxeVersion + '.h'), path.join(__appdir, 'ipxe', 'ipxe_' + ipxeVersion, 'src', 'config', 'console.h')) } function updateInProgress (ipxeVersion, inProgress) { building[ipxeVersion] = inProgress const event = ipxeVersion + ' inProgress' io.in('broadcast ipxeBuild').emit(event, inProgress) } function sendToLog (ipxeVersion, msg, status, log = true) { const date = new Date() const pad = x => x < 10 ? '0' + x : x var dateString = '[' + date.getFullYear() + '-' dateString += pad(date.getMonth()) + '-' dateString += pad(date.getDate()) + ' ' dateString += pad(date.getHours()) + ':' dateString += pad(date.getMinutes()) + ':' dateString += pad(date.getSeconds()) + ']' const logEntry = { date: dateString, status: status, msg: msg } const event = ipxeVersion + ' log' io.in('broadcast ipxeBuild').emit(event, logEntry) if (log) writeLog(ipxeVersion, logEntry) } function writeLog (ipxeVersion, logEntry) { fs.writeFile(path.join(__appdir, 'ipxe', 'log_' + ipxeVersion + '.txt'), logEntry.date + '\t' + logEntry.status + '\t' + logEntry.msg, { flag: 'a+' }, (err) => { if (err) throw err }) }