summaryrefslogtreecommitdiffstats
path: root/webapp
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 /webapp
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 'webapp')
-rw-r--r--webapp/src/components/IpxeBuilderModule.vue63
-rw-r--r--webapp/src/components/IpxeBuilderModuleConfig.vue224
-rw-r--r--webapp/src/config/dashboard.js4
-rw-r--r--webapp/src/config/i18n.js6
4 files changed, 294 insertions, 3 deletions
diff --git a/webapp/src/components/IpxeBuilderModule.vue b/webapp/src/components/IpxeBuilderModule.vue
new file mode 100644
index 0000000..9cb9bea
--- /dev/null
+++ b/webapp/src/components/IpxeBuilderModule.vue
@@ -0,0 +1,63 @@
+<i18n>
+{
+ "en": {
+ "efi": "EFI",
+ "bios": "BIOS"
+ },
+ "de": {
+ "efi": "EFI",
+ "bios": "BIOS"
+ }
+}
+</i18n>
+
+<template>
+ <v-container fill-height>
+ <v-layout>
+ <v-flex class="tabs-wrapper" xl10 offset-xl1 lg12>
+ <v-card>
+ <v-tabs v-model="tabs" centered :dark="tabsDark" :color="tabsColor" :slider-color="tabsSliderColor">
+ <v-tab>{{ $t('efi') }}</v-tab>
+ <v-tab>{{ $t('bios') }}</v-tab>
+ </v-tabs>
+ </v-card>
+
+ <v-tabs-items v-model="tabs" style="padding-bottom: 20px">
+ <v-tab-item>
+ <ipxe-builder-module-config :ipxeVersion="'efi'"></ipxe-builder-module-config>
+ </v-tab-item>
+ <v-tab-item>
+ <ipxe-builder-module-config :ipxeVersion="'bios'"></ipxe-builder-module-config>
+ </v-tab-item>
+
+ </v-tabs-items>
+ </v-flex>
+ </v-layout>
+ </v-container>
+</template>
+
+<script>
+import { mapGetters } from 'vuex'
+import IpxeBuilderModuleConfig from '@/components/IpxeBuilderModuleConfig'
+
+export default {
+ name: 'IpxeBuilder',
+ components: {
+ IpxeBuilderModuleConfig
+ },
+ data () {
+ return {
+ tabs: 0
+ }
+ },
+ computed: {
+ ...mapGetters(['tabsDark', 'tabsColor', 'tabsSliderColor'])
+ },
+ watch: {
+ },
+ methods: {
+ },
+ created () {
+ }
+}
+</script>
diff --git a/webapp/src/components/IpxeBuilderModuleConfig.vue b/webapp/src/components/IpxeBuilderModuleConfig.vue
new file mode 100644
index 0000000..e4f619a
--- /dev/null
+++ b/webapp/src/components/IpxeBuilderModuleConfig.vue
@@ -0,0 +1,224 @@
+<i18n>
+{
+ "en": {
+ "efi": "EFI",
+ "bios": "BIOS",
+ "general": "general.h",
+ "console": "console.h",
+ "script": "Embedded script (EMBED=)",
+ "trust": "Embedded certificate (TRUST=)",
+ "ipxe": "iPXE",
+ "buildIpxe": "Build iPXE",
+ "scriptSaved": "Embedded script saved successfully",
+ "certificateSaved": "Certificate saved successfully",
+ "generalSaved": "general.h saved successfully",
+ "consoleSaved": "console.h saved successfully",
+ "buildingIpxe": "Building iPXE ...",
+ "cleanIpxe": "Clean iPXE",
+ "cleaningIpxe": "Cleaning iPXE ..."
+ },
+ "de": {
+ "efi": "EFI",
+ "bios": "BIOS",
+ "general": "general.h",
+ "console": "console.h",
+ "script": "Eingebettetes Skript (EMBED=)",
+ "trust": "Eingebettetes Zertifikat (TRUST=)",
+ "ipxe": "iPXE",
+ "buildIpxe": "iPXE bauen",
+ "scriptSaved": "Eingebettetes Skript wurde erfolgreich gespeichert",
+ "certificateSaved": "Zertifikat wurde erfolgreich gespeichert",
+ "generalSaved": "general.h wurde erfolgreich gespeichert",
+ "consoleSaved": "console.h wurde erfolgreich gespeichert",
+ "buildingIpxe": "iPXE wird gebaut ...",
+ "cleanIpxe": "iPXE aufräumen",
+ "cleaningIpxe": "iPXE wird aufgeräumt .."
+ }
+}
+</i18n>
+
+<template>
+ <div>
+
+ <v-subheader>{{ $t('ipxe') }}</v-subheader>
+ <v-card style="padding-left: 24px;padding-right: 24px; padding-top: 12px; padding-bottom: 12px; height: 50vh; overflow: auto;" ref="log">
+ <template v-for="(entry, index) in log">
+ <pre :class="entry.status + '--text'" style="margin-bottom: 0px" :key="index"><span>{{ entry.date }} {{ entry.msg }}</span></pre>
+ </template>
+ </v-card>
+ <div class="text-xs-right">
+ <v-btn flat color="error" @click="cleanIpxe"><v-icon left>delete</v-icon>{{ $t('cleanIpxe') }}</v-btn>
+ <v-btn flat color="primary" @click="buildIpxe"><v-icon left>gavel</v-icon>{{ $t('buildIpxe') }}</v-btn>
+ </div>
+
+ <v-subheader></v-subheader>
+ <v-expansion-panel v-model="scriptExpanded">
+ <v-expansion-panel-content>
+ <div slot="header">{{ $t('script') }}</div>
+ <v-card>
+ <codemirror class="script-editor" ref="script" v-model="script"></codemirror>
+ </v-card>
+ <!--<v-divider></v-divider>-->
+ <div class="text-xs-right">
+ <v-btn flat color="error" @click="undo('script')"><v-icon left>undo</v-icon>{{ $t('undo') }}</v-btn>
+ <v-btn flat color="success" @click="redo('script')"><v-icon left>redo</v-icon>{{ $t('redo') }}</v-btn>
+ <v-btn color="primary" @click="save('script')"><v-icon left>save</v-icon>{{ $t('save') }}</v-btn>
+ </div>
+ </v-expansion-panel-content>
+ </v-expansion-panel>
+
+ <v-subheader></v-subheader>
+ <v-expansion-panel v-model="certificateExpanded">
+ <v-expansion-panel-content>
+ <div slot="header">{{ $t('trust') }}</div>
+ <v-card>
+ <codemirror class="script-editor" ref="certificate" v-model="certificate"></codemirror>
+ </v-card>
+ <!--<v-divider></v-divider>-->
+ <div class="text-xs-right">
+ <v-btn flat color="error" @click="undo('certificate')"><v-icon left>undo</v-icon>{{ $t('undo') }}</v-btn>
+ <v-btn flat color="success" @click="redo('certificate')"><v-icon left>redo</v-icon>{{ $t('redo') }}</v-btn>
+ <v-btn color="primary" @click="save('certificate')"><v-icon left>save</v-icon>{{ $t('save') }}</v-btn>
+ </div>
+ </v-expansion-panel-content>
+ </v-expansion-panel>
+
+ <v-subheader></v-subheader>
+ <v-expansion-panel v-model="generalExpanded">
+ <v-expansion-panel-content>
+ <div slot="header">{{ $t('general') }}</div>
+ <v-card>
+ <codemirror class="script-editor" ref="general" v-model="general"></codemirror>
+ </v-card>
+ <!--<v-divider></v-divider>-->
+ <div class="text-xs-right">
+ <v-btn flat color="error" @click="undo('general')"><v-icon left>undo</v-icon>{{ $t('undo') }}</v-btn>
+ <v-btn flat color="success" @click="redo('general')"><v-icon left>redo</v-icon>{{ $t('redo') }}</v-btn>
+ <v-btn color="primary" @click="save('general')"><v-icon left>save</v-icon>{{ $t('save') }}</v-btn>
+ </div>
+ </v-expansion-panel-content>
+ </v-expansion-panel>
+
+ <v-subheader></v-subheader>
+ <v-expansion-panel v-model="consoleExpanded">
+ <v-expansion-panel-content>
+ <div slot="header">{{ $t('console') }}</div>
+ <v-card>
+ <codemirror class="script-editor" ref="console" v-model="console"></codemirror>
+ </v-card>
+ <!--<v-divider></v-divider>-->
+ <div class="text-xs-right">
+ <v-btn flat color="error" @click="undo('console')"><v-icon left>undo</v-icon>{{ $t('undo') }}</v-btn>
+ <v-btn flat color="success" @click="redo('console')"><v-icon left>redo</v-icon>{{ $t('redo') }}</v-btn>
+ <v-btn color="primary" @click="save('console')"><v-icon left>save</v-icon>{{ $t('save') }}</v-btn>
+ </div>
+ </v-expansion-panel-content>
+ </v-expansion-panel>
+
+ </div>
+</template>
+
+<script>
+import { mapGetters } from 'vuex'
+import axios from 'axios'
+
+export default {
+ name: 'IpxeBuilder',
+ props: ['ipxeVersion'],
+ components: {
+ },
+ data () {
+ return {
+ tabs: 0,
+ script: '',
+ certificate: '',
+ general: '',
+ console: '',
+ scriptExpanded: null,
+ certificateExpanded: null,
+ generalExpanded: null,
+ consoleExpanded: null,
+ log: []
+ }
+ },
+ computed: {
+ ...mapGetters(['tabsDark', 'tabsColor', 'tabsSliderColor'])
+ },
+ watch: {
+ scriptExpanded: function () {
+ if (this.scriptExpanded === 0) this.$refs.script.refresh()
+ },
+ certificateExpanded: function () {
+ if (this.certificateExpanded === 0) this.$refs.certificate.refresh()
+ },
+ generalExpanded: function () {
+ if (this.generalExpanded === 0) this.$refs.general.refresh()
+ },
+ consoleExpanded: function () {
+ if (this.consoleExpanded === 0) this.$refs.console.refresh()
+ }
+ },
+ methods: {
+ save (apiPath) {
+ axios.put('/api/ipxe/' + this.ipxeVersion + '/' + apiPath, { data: this[apiPath] }).then(result => {
+ const saveMsg = apiPath + 'Saved'
+ if (result.data.status === 'SUCCESS') this.$snackbar({ color: 'success', text: this.$tc(saveMsg) })
+ else this.$snackbar({ color: 'error', text: result.data.error })
+ })
+ },
+ undo (element) {
+ this.$refs[element].codemirror.undo()
+ },
+ redo (element) {
+ this.$refs[element].codemirror.redo()
+ },
+ buildIpxe () {
+ axios.get('/api/ipxe/' + this.ipxeVersion + '/build').then(result => {
+ this.$snackbar({ color: 'primary', text: this.$tc('buildingIpxe') })
+ })
+ },
+ cleanIpxe () {
+ axios.get('/api/ipxe/' + this.ipxeVersion + '/clean').then(result => {
+ this.$snackbar({ color: 'primary', text: this.$tc('cleaningIpxe') })
+ })
+ }
+ },
+ created () {
+ // Load the data.
+ axios.get('/api/ipxe/' + this.ipxeVersion + '/script').then(result => {
+ this.script = result.data
+ })
+ axios.get('/api/ipxe/' + this.ipxeVersion + '/certificate').then(result => {
+ this.certificate = result.data
+ })
+ axios.get('/api/ipxe/' + this.ipxeVersion + '/general').then(result => {
+ this.general = result.data
+ })
+ axios.get('/api/ipxe/' + this.ipxeVersion + '/console').then(result => {
+ this.console = result.data
+ })
+
+ axios.get('/api/ipxe/' + this.ipxeVersion + '/log').then(result => {
+ var lines = result.data.split('\n')
+ for (var line in lines) {
+ if (lines[line] === '') continue
+ var attr = lines[line].split('\t')
+ this.log.push({ date: attr[0], status: attr[1], msg: attr[2] })
+ }
+ })
+
+ // Socket io event listeners
+ this.$socket.on(this.ipxeVersion + ' log', entry => {
+ this.log.push({ msg: entry.msg, status: entry.status, date: entry.date })
+ })
+ },
+ updated () {
+ this.$refs.log.$el.scrollTop = this.$refs.log.$el.scrollHeight
+ }
+}
+</script>
+
+<!-- Add "scoped" attribute to limit CSS to this component only -->
+<style scoped>
+
+</style>
diff --git a/webapp/src/config/dashboard.js b/webapp/src/config/dashboard.js
index a092cdc..ac8a7b1 100644
--- a/webapp/src/config/dashboard.js
+++ b/webapp/src/config/dashboard.js
@@ -3,11 +3,13 @@ import ConfiguratorModule from '@/components/ConfiguratorModule'
import RegistrationModule from '@/components/RegistrationModule'
import BackendModule from '@/components/BackendModule'
import PermissionModule from '@/components/PermissionModule'
+import IpxeBuilder from '@/components/IpxeBuilderModule'
export default [
{ path: 'groups', component: GroupModule, icon: 'category' },
{ path: 'configurator', component: ConfiguratorModule, icon: 'list' },
{ path: 'registration', component: RegistrationModule, icon: 'assignment' },
{ path: 'backends', component: BackendModule, icon: 'cloud' },
- { path: 'permissions', component: PermissionModule, icon: 'lock_open' }
+ { path: 'permissions', component: PermissionModule, icon: 'lock_open' },
+ { path: 'ipxe', component: IpxeBuilder, icon: 'merge_type' }
]
diff --git a/webapp/src/config/i18n.js b/webapp/src/config/i18n.js
index 818f57c..3f71729 100644
--- a/webapp/src/config/i18n.js
+++ b/webapp/src/config/i18n.js
@@ -27,7 +27,8 @@ export default {
'ConfiguratorModule': 'iPXE Configurator',
'RegistrationModule': 'Client Registration',
'BackendModule': 'External Backends',
- 'PermissionModule': 'Permission Manager'
+ 'PermissionModule': 'Permission Manager',
+ 'IpxeBuilder': 'iPXE Builder'
}
},
'de': {
@@ -58,7 +59,8 @@ export default {
'ConfiguratorModule': 'iPXE Konfigurator',
'RegistrationModule': 'Client Registrierung',
'BackendModule': 'Externe Backends',
- 'PermissionModule': 'Rechteverwaltung'
+ 'PermissionModule': 'Rechteverwaltung',
+ 'IpxeBuilder': 'iPXE Builder'
}
}
}