summaryrefslogtreecommitdiffstats
path: root/server/lib/shell.js
blob: 080e5d637e2b4017fec86fe317575e114efc4674 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
// 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: async function (req, res) {
    const ipxeVersion = req.params.version

    // 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'))

    // 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)
  }
}

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'))
}

function sendToLog (ipxeVersion, msg, status, log = 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 (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
  })
}