/* global __appdir */ var path = require('path') var shell = require('shelljs') var io = require(path.join(__appdir, 'lib', 'socketio')) const fs = require('fs') // Only one building process per version at a time. module.exports = { buildIpxe: async function (buildParameters = [], gitURL = 'http://git.ipxe.org/ipxe.git', gitBranch = '') { var makeCmd = '' // Only one building process can be running. (lock the ipxe directory) // TODO: // If file is already locked // if (false) return { status: 'ALREADY_BUILDING', error: 'iPXE-building process is already in progress.' } makeCmd = 'make ' + buildParameters.join(' ') makeCmd += ' EMBED=' + path.join(__appdir, 'ipxe', 'embedded.ipxe') makeCmd += ' TRUST=' + path.join(__appdir, 'bin', 'fullchain.pem') // Cloning git. sendToLog('Cloning git ...\n', 'primary') await cloneIpxe(gitURL, gitBranch) // Copying configs. sendToLog('Copying configs ...\n', 'primary') copyConfigs() // Make ipxe. sendToLog('Make iPXE ...\n', 'primary') shell.cd(path.join(__appdir, 'ipxe', 'ipxeGIT', 'src')) await new Promise((resolve, reject) => { const process = shell.exec(makeCmd, { async: true }, () => { resolve() }) // Send the output to the frontend log. process.stdout.on('data', data => { const multiline = data.split('\n') if (multiline.length > 2) { multiline.forEach(line => { if (line) sendToLog(line, 'normal') }) } else sendToLog(data, 'normal') }) process.stderr.on('data', data => { const multiline = data.split('\n') if (multiline.length > 2) { multiline.forEach(line => { if (line) sendToLog(line, 'error') }) } else sendToLog(data, 'error') }) }) // Copy and rename the ipxe file to the __appdir/ipxe/builds/ dir. sendToLog('Copying ipxe file(s) ...\n', 'primary') const date = new Date() const timestamp = date.getFullYear() + '-' + ('0' + (date.getMonth() + 1)).slice(-2) + '-' + ('0' + date.getDate()).slice(-2) + '_' + ('0' + date.getHours()).slice(-2) + '-' + ('0' + date.getMinutes()).slice(-2) + '-' + ('0' + date.getSeconds()).slice(-2) for (let buildtarget of buildParameters) { const target = buildtarget.split('/') shell.mkdir('-p', path.join(__appdir, 'ipxe', 'builds', timestamp, target[0])) shell.cp(path.join(__appdir, 'ipxe', 'ipxeGIT', 'src', buildtarget), path.join(__appdir, 'ipxe', 'builds', timestamp, target[0], target[1])) sendToLog('Copyed ' + buildtarget, 'success') } sendToLog('Finished copying\n', 'success') // sendToLog(ipxeVersion, 'done\n', 'success') // shell.mv(path.join(__appdir, 'ipxe', 'undionly.kpxe'), path.join(__appdir, 'ipxe', 'ipxe.' + ipxeVersion)) // updateInProgress(ipxeVersion, false) }, cancelBuilding: async function () { /* const ipxeVersion = req.params.version const process = make[ipxeVersion] if (process) { const kill = 'pkill -P ' + process.pid shell.exec(kill) updateInProgress(ipxeVersion, false) } res.send({ status: 'SUCCESS', data: process }) */ }, clean: async function () { // If building return // return { status: 'ALREADY_BUILDING', error: 'Can\'t clean, while iPXE-building is in progress.' } // TODO more logging of what get's deleted shell.cd(path.join(__appdir, 'ipxe')) shell.rm('-rf', 'ipxeGIT') shell.rm(path.join(__appdir, 'ipxe', 'ipxelog.txt')) sendToLog('iPXE files successfully cleaned', 'success', false) return { status: 'SUCCESS', msg: 'Cleaning iPXE started' } }, status: function (ipxeVersion) { return false }, /* Changes or creates a symbolic link to a builded ipxe */ forceSymlink: function (source, dest) { // Because of the shelljs lib is bugged handle broken links deletetion myself var destinationExists try { fs.lstatSync(dest) destinationExists = true } catch (err) { destinationExists = false } if (destinationExists) { fs.unlinkSync(dest) } const ln = shell.ln('-sf', source, dest) if (ln.stderr) return { status: 'ERROR', error: ln.stderr } else return { status: 'SUCCESS' } }, readdirRecursive: function (buildsPath) { let structure = [] try { const directory = fs.readdirSync(buildsPath) for (let obj of directory) { if (!fs.lstatSync(path.join(buildsPath, obj)).isDirectory()) { structure.push({ name: obj, type: 'file' }) } else { structure.push({ name: obj, type: 'directory', children: this.readdirRecursive(path.join(buildsPath, obj)) }) } } } catch (error) { return [] } return structure }, forceDeleteBuild: function (buildsPath) { shell.rm('-rf', path.join(buildsPath)) } } async function cloneIpxe (url, branch) { // 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) => { let command = 'git clone ' + url if (branch) command += ' --branch ' + branch + ' --single-branch' var clone = shell.exec(command + ' ipxeGIT', { async: true }, () => { resolve() }) clone.stdout.on('data', data => { sendToLog(data, 'normal') }) clone.stderr.on('data', data => { sendToLog(data, 'error') }) }) } function copyConfigs (ipxeVersion) { // Remove the default configs and paste in the customized ones. shell.rm(path.join(__appdir, 'ipxe', 'ipxeGIT', 'src', 'config', 'general.h')) shell.rm(path.join(__appdir, 'ipxe', 'ipxeGIT', 'src', 'config', 'console.h')) shell.cp(path.join(__appdir, 'ipxe', 'general.h'), path.join(__appdir, 'ipxe', 'ipxeGIT', 'src', 'config', 'general.h')) shell.cp(path.join(__appdir, 'ipxe', 'console.h'), path.join(__appdir, 'ipxe', 'ipxeGIT', 'src', 'config', 'console.h')) } function sendToLog (msg, status, log = true) { const date = new Date() const pad = x => x < 10 ? '0' + x : x var dateString = '[' + date.getFullYear() + '-' dateString += pad(date.getMonth() + 1) + '-' 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 = 'log' io.in('broadcast ipxeBuild').emit(event, logEntry) if (log) writeLog(logEntry) } function writeLog (logEntry) { fs.writeFile(path.join(__appdir, 'ipxe', 'ipxelog.txt'), logEntry.date + '\t' + logEntry.status + '\t' + logEntry.msg, { flag: 'a+' }, (err) => { if (err) throw err }) }