summaryrefslogtreecommitdiffstats
path: root/server
diff options
context:
space:
mode:
authorJannik Schönartz2019-01-15 04:39:31 +0100
committerJannik Schönartz2019-01-15 04:39:31 +0100
commitffc5050fcdd0efed4f01d7f1f20465cadd9c9f5b (patch)
tree52fa04038927c99b737a5afbcecddd0ae65070f8 /server
parent[webapp/datatable] Add search clear + show all selected button (diff)
downloadbas-ffc5050fcdd0efed4f01d7f1f20465cadd9c9f5b.tar.gz
bas-ffc5050fcdd0efed4f01d7f1f20465cadd9c9f5b.tar.xz
bas-ffc5050fcdd0efed4f01d7f1f20465cadd9c9f5b.zip
[ipxe builder] Add ipxe builder module
EFI and BIOS version can be build and configured Fancy log to see the stdout and stderr
Diffstat (limited to 'server')
-rw-r--r--server/api/ipxe.js63
-rw-r--r--server/ipxe/embedded_bios.ipxe15
-rw-r--r--server/ipxe/embedded_efi.ipxe (renamed from server/ipxe/main.ipxe)5
-rw-r--r--server/lib/shell.js144
-rw-r--r--server/lib/socketio.js1
5 files changed, 191 insertions, 37 deletions
diff --git a/server/api/ipxe.js b/server/api/ipxe.js
index f50d9d3..549eb6f 100644
--- a/server/api/ipxe.js
+++ b/server/api/ipxe.js
@@ -7,12 +7,71 @@ var router = express.Router()
var noAuthRouter = express.Router()
// GET requests.
+router.get('/build', (req, res) => {
+ shell.buildIpxe(req, res)
+})
+
+router.get('/:version/script', (req, res) => {
+ res.setHeader('content-type', 'text/plain')
+ res.sendFile(path.join(__appdir, 'ipxe', 'embedded_' + req.params.version + '.ipxe'))
+})
+
+router.get('/:version/certificate', (req, res) => {
+ res.setHeader('content-type', 'text/plain')
+ res.sendFile(path.join(__appdir, 'bin', 'fullchain.pem'))
+})
+
+router.get('/:version/general', (req, res) => {
+ res.setHeader('content-type', 'text/plain')
+ res.sendFile(path.join(__appdir, 'ipxe', 'general_' + req.params.version + '.h'))
+})
+
+router.get('/:version/console', (req, res) => {
+ res.setHeader('content-type', 'text/plain')
+ res.sendFile(path.join(__appdir, 'ipxe', 'console_' + req.params.version + '.h'))
+})
+
+router.get('/:version/log', async (req, res) => {
+ res.setHeader('content-type', 'text/plain')
+ const filepath = path.join(__appdir, 'ipxe', 'log_' + req.params.version + '.txt')
+ res.sendFile(filepath, err => {
+ if (err) console.log('Could not send file ' + filepath)
+ })
+})
+
+router.put('/:version/:filename', (req, res) => {
+ var filepath = null
+ // Set the file path
+ if (req.params.filename === 'script') {
+ filepath = path.join(__appdir, 'ipxe', 'embedded_' + req.params.version + '.ipxe')
+ } else if (req.params.filename === 'console' || req.params.filename === 'general') {
+ filepath = path.join(__appdir, 'ipxe', req.params.filename + '_' + req.params.version + '.h')
+ } else if (req.params.filename === 'certificate') {
+ filepath = path.join(__appdir, 'bin', 'fullchain.pem')
+ } else {
+ res.status(500).send({ status: 'UNKNOWN_FILENAME', error: 'The provided filename is unknown' })
+ return
+ }
+
+ // Write File
+ fs.writeFile(filepath, req.body.data, err => {
+ if (err) res.status(500).send({ status: 'WRITE_FILE_ERROR', error: err })
+ else res.status(200).send({ status: 'SUCCESS' })
+ })
+})
/*
* @return: Rebuild the ipxe.
*/
-router.get('/build', (req, res) => {
- shell.buildIpxe(req, res)
+router.get('/:version/build', async (req, res) => {
+ if (req.params.version === 'efi' || req.params.version === 'bios') await shell.buildIpxe(req, res)
+ res.status(200).send({ status: 'success' })
+})
+
+router.get('/:version/clean', (req, res) => {
+ if (req.params.version === 'efi') shell.clean('efi')
+ else if (req.params.version === 'bios') shell.clean('bios')
+ res.send()
})
module.exports.router = router
diff --git a/server/ipxe/embedded_bios.ipxe b/server/ipxe/embedded_bios.ipxe
new file mode 100644
index 0000000..698c683
--- /dev/null
+++ b/server/ipxe/embedded_bios.ipxe
@@ -0,0 +1,15 @@
+#!ipxe
+
+################
+# BIOS Version #
+################
+
+ifopen
+
+# Wallpaper
+set img tftp://10.8.102.124/ipxeWallpaper3_scale.png || shell
+console --picture ${img} --x 800 --y 600 || shell
+
+:loop
+chain https://bas.intra.uni-freiburg.de/api/configloader/${uuid}
+goto loop \ No newline at end of file
diff --git a/server/ipxe/main.ipxe b/server/ipxe/embedded_efi.ipxe
index 3bb8e86..70bfc17 100644
--- a/server/ipxe/main.ipxe
+++ b/server/ipxe/embedded_efi.ipxe
@@ -1,4 +1,9 @@
#!ipxe
+
+################
+# EFI Version #
+################
+
ifopen
# Wallpaper
diff --git a/server/lib/shell.js b/server/lib/shell.js
index 2b1ea0b..09a3ae2 100644
--- a/server/lib/shell.js
+++ b/server/lib/shell.js
@@ -1,47 +1,121 @@
+// Those packages needs to be installed to build ipxe:
+// sudo apt install liblzma-dev
+// sudo apt install mkisofs
+
/* global __appdir */
var path = require('path')
var shell = require('shelljs')
var ipxeGIT = 'git://git.ipxe.org/ipxe.git'
+var io = require(path.join(__appdir, 'lib', 'socketio'))
+const fs = require('fs')
module.exports = {
- buildIpxe: function (req, res) {
- if (!shell.which('git')) {
- return res.status(500).send({ status: 'GIT_MISSING', error_message: 'Please install git on the server.' })
- }
+ buildIpxe: async function (req, res) {
+ const ipxeVersion = req.params.version
+
+ // Cloning git.
+ sendToLog(ipxeVersion, 'Cloning git ...\n', 'primary')
+ await cloneIpxe(ipxeVersion)
- var gitclone = 'git clone ' + ipxeGIT
- shell.cd(path.join(__appdir, 'ipxe'))
- shell.exec(gitclone, function (code, stdout, stderr) {
- shell.cd(path.join(__appdir, 'ipxe', 'ipxe', 'src'))
-
- // Remove the general config and paste in the own one
- shell.rm(path.join(__appdir, 'ipxe', 'ipxe', 'src', 'config', 'general.h'))
- // shell.cp(path.join(__appdir, 'ipxe', 'general.h'), path.join(__appdir, 'ipxe', 'ipxe', 'src', 'config'))
- shell.cp(path.join(__appdir, 'ipxe', 'general_efi.h'), path.join(__appdir, 'ipxe', 'ipxe', 'src', 'config', 'general.h'))
- shell.rm(path.join(__appdir, 'ipxe', 'ipxe', 'src', 'config', 'console.h'))
- // shell.cp(path.join(__appdir, 'ipxe', 'console.h'), path.join(__appdir, 'ipxe', 'ipxe', 'src', 'config'))
- shell.cp(path.join(__appdir, 'ipxe', 'console_efi.h'), path.join(__appdir, 'ipxe', 'ipxe', 'src', 'config', 'console.h'))
- // PCBIOS Variant
- // var make = 'make EMBED=' + path.join(__appdir, 'ipxe', 'main.ipxe') + ' TRUST=' + path.join(__appdir, 'bin', 'fullchain.pem')// + ' bin/undionly.kpxe'
-
- // EFI Variant
- var make = 'make bin-x86_64-efi/snponly.efi EMBED=' + path.join(__appdir, 'ipxe', 'main.ipxe') + ' TRUST=' + path.join(__appdir, 'bin', 'fullchain.pem')// + ' bin/undionly.kpxe'
-
- // USB
- // var make = 'make EMBED=' + path.join(__appdir, 'ipxe', 'reboot.ipxe') + ' TRUST=' + path.join(__appdir, 'bin', 'fullchain.pem') + ' bin/ipxe.usb'
- shell.env.DEBUG = ''
- shell.exec(make, function (code, stdout, stderr) {
- // shell.rm(path.join(__appdir, 'tftp', 'ipxe.0'))
- shell.rm(path.join(__appdir, 'ipxe', 'ipxe.0'))
- // shell.cp('bin/undionly.kpxe', path.join(__appdir, 'tftp'))
- shell.cp('bin/undionly.kpxe', path.join(__appdir, 'ipxe'))
- shell.mv(path.join(__appdir, 'ipxe', 'undionly.kpxe'), path.join(__appdir, 'ipxe', 'ipxe.0'))
- // shell.rm('-rf', 'ipxe');
- return res.status(200).send({ status: 'success' })
+ // 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'))
+
+ // Different make command for efi / bios are needed.
+ var makeCmd = ''
+ if (ipxeVersion === 'efi') 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'
+ else if (ipxeVersion === 'bios') makeCmd = 'make EMBED=' + path.join(__appdir, 'ipxe', 'embedded_' + ipxeVersion + '.ipxe') + ' TRUST=' + path.join(__appdir, 'bin', 'fullchain.pem')// + ' bin/undionly.kpxe'
+ await new Promise((resolve, reject) => {
+ var make = shell.exec(makeCmd, { async: true }, () => {
+ resolve()
+ })
+
+ // Send the output to the frontend log.
+ make.stdout.on('data', data => {
+ sendToLog(ipxeVersion, data, 'normal')
+ })
+ make.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))
+ },
+
+ clean: async function (ipxeVersion) {
+ 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'))
+ sendToLog(ipxeVersion, 'iPXE files successfully cleaned', 'success', false)
}
}
-// sudo apt-get install liblzma-dev
-// sudo apt-get install mkisofs
+async function cloneIpxe(ipxeVersion) {
+ // Check if git is installed on the server.
+ if (!shell.which('git')) {
+ return { status: 'GIT_MISSING', error_message: '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'))
+ return
+}
+
+function sendToLog(ipxeVersion, msg, status, writeLog = true) {
+ var date = new Date();
+ var dateString = '[' + date.getFullYear() + '-'
+
+ var month = parseInt(date.getMonth()) + 1
+ if (month < 10) dateString += '0' + month + '-'
+ else dateString += month + '-'
+
+ if (parseInt(date.getDate()) < 10) dateString += '0' + date.getDate() + ' '
+ else dateString += date.getDate() + ' '
+
+ if (parseInt(date.getHours()) < 10) dateString += '0' + date.getHours() + ':'
+ else dateString += date.getHours() + ':'
+
+ if (parseInt(date.getMinutes()) < 10) dateString += '0' + date.getMinutes() + ':'
+ else dateString += date.getMinutes() + ':'
+
+ if (parseInt(date.getSeconds()) < 10) dateString += '0' + date.getSeconds()
+ else dateString += date.getSeconds()
+ dateString += ']'
+
+ var logEntry = { date: dateString, status: status, msg: msg }
+
+ var socket = ipxeVersion + ' log'
+ io.in('broadcast ipxeBuild').emit(socket, logEntry)
+ if (writeLog) 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
+ })
+}
diff --git a/server/lib/socketio.js b/server/lib/socketio.js
index 07c2f22..5cbedb7 100644
--- a/server/lib/socketio.js
+++ b/server/lib/socketio.js
@@ -27,6 +27,7 @@ io.on('connection', socket => {
// Join broadcast rooms (TODO: check if user has permission to join those rooms)
socket.join('broadcast newClient')
+ socket.join('broadcast ipxeBuild')
// Notification broadcasts
socket.on('notifications clearAll', () => socket.to(userId).emit('notifications clearAll'))