mirror of
https://github.com/kasmtech/kasm-install-wizard.git
synced 2026-07-17 16:35:08 +00:00
KASM-8264 fixed implicit globals, update vars, change loops, fix vulns
This commit is contained in:
parent
9bae28c7d4
commit
d7d5cd8f12
3 changed files with 65 additions and 66 deletions
71
index.js
71
index.js
|
|
@ -1,33 +1,32 @@
|
||||||
// Imports
|
// Imports
|
||||||
var Docker = require('dockerode');
|
const Docker = require('dockerode');
|
||||||
var socketIO = require('socket.io');
|
const socketIO = require('socket.io');
|
||||||
var pty = require("node-pty");
|
const pty = require("node-pty");
|
||||||
var fsw = require('fs').promises;
|
const fsw = require('fs').promises;
|
||||||
var fs = require('fs');
|
const fs = require('fs');
|
||||||
var os = require('os');
|
const os = require('os');
|
||||||
var yaml = require('js-yaml');
|
const yaml = require('js-yaml');
|
||||||
var _ = require('lodash');
|
const _ = require('lodash');
|
||||||
var si = require('systeminformation');
|
const si = require('systeminformation');
|
||||||
var express = require('express');
|
const express = require('express');
|
||||||
var app = require('express')();
|
const app = require('express')();
|
||||||
var privateKey = fs.readFileSync('/opt/kasm/certs/kasm_wizard.key', 'utf8');
|
const privateKey = fs.readFileSync('/opt/kasm/certs/kasm_wizard.key', 'utf8');
|
||||||
var certificate = fs.readFileSync('/opt/kasm/certs/kasm_wizard.crt', 'utf8');
|
const certificate = fs.readFileSync('/opt/kasm/certs/kasm_wizard.crt', 'utf8');
|
||||||
var credentials = {key: privateKey, cert: certificate};
|
const credentials = {key: privateKey, cert: certificate};
|
||||||
var https = require('https').Server(credentials, app);
|
const https = require('https').Server(credentials, app);
|
||||||
var baserouter = express.Router();
|
const baserouter = express.Router();
|
||||||
var docker = new Docker({socketPath: '/var/run/docker.sock'});
|
const docker = new Docker({socketPath: '/var/run/docker.sock'});
|
||||||
var arch = os.arch().replace('x64', 'amd64');
|
const arch = os.arch().replace('x64', 'amd64');
|
||||||
var baseUrl = process.env.SUBFOLDER || '/';
|
const baseUrl = process.env.SUBFOLDER || '/';
|
||||||
var version = process.env.VERSION || 'stable';
|
const port = process.env.KASM_PORT || '443';
|
||||||
var port = process.env.KASM_PORT || '443';
|
|
||||||
const { spawn } = require('node:child_process');
|
const { spawn } = require('node:child_process');
|
||||||
var EULA;
|
let EULA;
|
||||||
var images;
|
let images;
|
||||||
var currentVersion;
|
let currentVersion;
|
||||||
var sourceLocal = false;
|
let sourceLocal = false;
|
||||||
var gpuInfo;
|
let gpuInfo;
|
||||||
var installSettings = {};
|
let installSettings = {};
|
||||||
var upgradeSettings = {};
|
let upgradeSettings = {};
|
||||||
|
|
||||||
// Find the best matching compatibility entry for the current version.
|
// Find the best matching compatibility entry for the current version.
|
||||||
// Exact version match takes precedence over wildcard (e.g. "1.18.x").
|
// Exact version match takes precedence over wildcard (e.g. "1.18.x").
|
||||||
|
|
@ -186,17 +185,17 @@ async function setGpu(imagesI) {
|
||||||
let card = gpu.slice(-1);
|
let card = gpu.slice(-1);
|
||||||
let render = (Number(card) + 128).toString();
|
let render = (Number(card) + 128).toString();
|
||||||
// Handle NVIDIA Gpus
|
// Handle NVIDIA Gpus
|
||||||
var baseRun;
|
let baseRun;
|
||||||
if (gpuName.indexOf('NVIDIA') !== -1) {
|
if (gpuName.indexOf('NVIDIA') !== -1) {
|
||||||
baseRun = JSON.parse('{"runtime":"nvidia","environment":{"NVIDIA_DRIVER_CAPABILITIES":"all","KASM_EGL_CARD":"/dev/dri/card' + card + '","KASM_RENDERD":"/dev/dri/renderD' + render + '"},"device_requests":[{"driver": "","count": -1,"device_ids": null,"capabilities":[["gpu"]],"options":{}}]}');
|
baseRun = JSON.parse('{"runtime":"nvidia","environment":{"NVIDIA_DRIVER_CAPABILITIES":"all","KASM_EGL_CARD":"/dev/dri/card' + card + '","KASM_RENDERD":"/dev/dri/renderD' + render + '"},"device_requests":[{"driver": "","count": -1,"device_ids": null,"capabilities":[["gpu"]],"options":{}}]}');
|
||||||
} else {
|
} else {
|
||||||
baseRun = JSON.parse('{"environment":{"DRINODE":"/dev/dri/renderD' + render + '", "HW3D": true},"devices":["/dev/dri/card' + card + ':/dev/dri/card' + card + ':rwm","/dev/dri/renderD' + render + ':/dev/dri/renderD' + render + ':rwm"]}');
|
baseRun = JSON.parse('{"environment":{"DRINODE":"/dev/dri/renderD' + render + '", "HW3D": true},"devices":["/dev/dri/card' + card + ':/dev/dri/card' + card + ':rwm","/dev/dri/renderD' + render + ':/dev/dri/renderD' + render + ':rwm"]}');
|
||||||
}
|
}
|
||||||
let baseExec = JSON.parse('{"first_launch":{"user":"root","cmd": "bash -c \'chown -R kasm-user:kasm-user /dev/dri/*\'"}}');
|
let baseExec = JSON.parse('{"first_launch":{"user":"root","cmd": "bash -c \'chown -R kasm-user:kasm-user /dev/dri/*\'"}}');
|
||||||
for (var i=0; i<imagesI.images.length; i++) {
|
for (let i=0; i<imagesI.images.length; i++) {
|
||||||
console.log(imagesI.images[i]['run_config']);
|
console.log(imagesI.images[i]['run_config']);
|
||||||
finalRun = _.merge(imagesI.images[i]['run_config'], baseRun)
|
let finalRun = _.merge(imagesI.images[i]['run_config'], baseRun)
|
||||||
finalExec = _.merge(imagesI.images[i]['exec_config'], baseExec)
|
let finalExec = _.merge(imagesI.images[i]['exec_config'], baseExec)
|
||||||
imagesI.images[i]['run_config'] = finalRun;
|
imagesI.images[i]['run_config'] = finalRun;
|
||||||
imagesI.images[i]['exec_config'] = finalExec;
|
imagesI.images[i]['exec_config'] = finalExec;
|
||||||
}
|
}
|
||||||
|
|
@ -238,14 +237,14 @@ app.use(baseUrl, baserouter);
|
||||||
https.listen(3000);
|
https.listen(3000);
|
||||||
|
|
||||||
//// socketIO comms ////
|
//// socketIO comms ////
|
||||||
io = socketIO(https, {path: baseUrl + 'socket.io'});
|
const io = socketIO(https, {path: baseUrl + 'socket.io'});
|
||||||
io.on('connection', async function (socket) {
|
io.on('connection', async function (socket) {
|
||||||
// Run bash install with our custom flags
|
// Run bash install with our custom flags
|
||||||
async function install(data) {
|
async function install(data) {
|
||||||
// Determine install settings
|
// Determine install settings
|
||||||
installSettings = data[0];
|
installSettings = data[0];
|
||||||
var imagesI = data[1];
|
let imagesI = data[1];
|
||||||
installFlags = ['/kasm_release/install.sh', '-W', '-B' ,'-H', '-e', '-L', port, '-P', installSettings.adminPass, '-U', installSettings.userPass];
|
let installFlags = ['/kasm_release/install.sh', '-W', '-B' ,'-H', '-e', '-L', port, '-P', installSettings.adminPass, '-U', installSettings.userPass];
|
||||||
if (imagesI && typeof imagesI === 'object' && Array.isArray(imagesI.images) && imagesI.images.length < 10) {
|
if (imagesI && typeof imagesI === 'object' && Array.isArray(imagesI.images) && imagesI.images.length < 10) {
|
||||||
installFlags.push('-b');
|
installFlags.push('-b');
|
||||||
}
|
}
|
||||||
|
|
@ -281,7 +280,7 @@ io.on('connection', async function (socket) {
|
||||||
|
|
||||||
// Run bash upgrade with our custom flags
|
// Run bash upgrade with our custom flags
|
||||||
async function upgrade(data) {
|
async function upgrade(data) {
|
||||||
upgradeFlags = ['/kasm_release/upgrade.sh', '-L', port];
|
let upgradeFlags = ['/kasm_release/upgrade.sh', '-L', port];
|
||||||
|
|
||||||
// Patch service image tags for rolling builds
|
// Patch service image tags for rolling builds
|
||||||
await appendRollingToServiceImages();
|
await appendRollingToServiceImages();
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,7 @@
|
||||||
"author": "",
|
"author": "",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"dockerode": "^3.3.2",
|
"dockerode": "^4.0.10",
|
||||||
"express": "^4.18.1",
|
"express": "^4.18.1",
|
||||||
"js-yaml": "^4.1.0",
|
"js-yaml": "^4.1.0",
|
||||||
"lodash": "^4.17.21",
|
"lodash": "^4.17.21",
|
||||||
|
|
|
||||||
|
|
@ -1,21 +1,21 @@
|
||||||
// Variables
|
// Variables
|
||||||
var EULA;
|
let EULA;
|
||||||
var images;
|
let images;
|
||||||
var gpus;
|
let gpus;
|
||||||
var term;
|
let term;
|
||||||
var installImages = [];
|
let installImages = [];
|
||||||
var installSettings = {};
|
const installSettings = {};
|
||||||
var upgradeSettings = {};
|
const upgradeSettings = {};
|
||||||
var currentVersion = '';
|
let currentVersion = '';
|
||||||
var isUpgrade = false;
|
let isUpgrade = false;
|
||||||
var selected = false;
|
let selected = false;
|
||||||
|
|
||||||
// Socket.io connection
|
// Socket.io connection
|
||||||
var host = window.location.hostname;
|
const host = window.location.hostname;
|
||||||
var port = window.location.port;
|
const port = window.location.port;
|
||||||
var protocol = window.location.protocol;
|
const protocol = window.location.protocol;
|
||||||
var path = window.location.pathname;
|
const path = window.location.pathname;
|
||||||
var socket = io(protocol + '//' + host + ':' + port, { path: path + 'socket.io'});
|
const socket = io(protocol + '//' + host + ':' + port, { path: path + 'socket.io'});
|
||||||
|
|
||||||
//// Page Functions ////
|
//// Page Functions ////
|
||||||
|
|
||||||
|
|
@ -33,7 +33,7 @@ async function install() {
|
||||||
if (installImages.length == 0) {
|
if (installImages.length == 0) {
|
||||||
socket.emit('install', [installSettings, false]);
|
socket.emit('install', [installSettings, false]);
|
||||||
} else {
|
} else {
|
||||||
for await (let image of installImages) {
|
for (let image of installImages) {
|
||||||
let srcImage = images.images.find(x => x.friendly_name === image);
|
let srcImage = images.images.find(x => x.friendly_name === image);
|
||||||
if (!srcImage) {
|
if (!srcImage) {
|
||||||
alert('Error: image "' + image + '" not found. Please refresh and try again.');
|
alert('Error: image "' + image + '" not found. Please refresh and try again.');
|
||||||
|
|
@ -71,7 +71,7 @@ function showTerminal() {
|
||||||
$('#terminal').empty();
|
$('#terminal').empty();
|
||||||
$('#terminal').css('display', 'block');
|
$('#terminal').css('display', 'block');
|
||||||
term = new Terminal();
|
term = new Terminal();
|
||||||
fitaddon = new FitAddon.FitAddon();
|
let fitaddon = new FitAddon.FitAddon();
|
||||||
term.loadAddon(fitaddon);
|
term.loadAddon(fitaddon);
|
||||||
term.open($('#terminal')[0]);
|
term.open($('#terminal')[0]);
|
||||||
fitaddon.fit();
|
fitaddon.fit();
|
||||||
|
|
@ -112,14 +112,14 @@ async function renderDash(data) {
|
||||||
// Store GPU info
|
// Store GPU info
|
||||||
$('body').data('gpuInfo', info.gpuInfo);
|
$('body').data('gpuInfo', info.gpuInfo);
|
||||||
// Upgrade button if needed
|
// Upgrade button if needed
|
||||||
var upgrade;
|
let upgrade;
|
||||||
if (info.currentVersion !== info.localVersion) {
|
if (info.currentVersion !== info.localVersion) {
|
||||||
upgrade = $('<button>', {class: 'btn btn-primary', onclick: 'renderUpgrade()'}).text('Upgrade to ' + info.currentVersion)
|
upgrade = $('<button>', {class: 'btn btn-primary', onclick: 'renderUpgrade()'}).text('Upgrade to ' + info.currentVersion)
|
||||||
} else {
|
} else {
|
||||||
upgrade = info.currentVersion;
|
upgrade = info.currentVersion;
|
||||||
}
|
}
|
||||||
// Kasm docker containers
|
// Kasm docker containers
|
||||||
containersTable = $('<tbody>');
|
let containersTable = $('<tbody>');
|
||||||
containersTable.append(
|
containersTable.append(
|
||||||
$('<tr>').append([
|
$('<tr>').append([
|
||||||
$('<th>').text('Web URL'),
|
$('<th>').text('Web URL'),
|
||||||
|
|
@ -134,7 +134,7 @@ async function renderDash(data) {
|
||||||
$('<td>').append(upgrade)
|
$('<td>').append(upgrade)
|
||||||
])
|
])
|
||||||
);
|
);
|
||||||
for await (let container of info.containers) {
|
for (let container of info.containers) {
|
||||||
containersTable.append(
|
containersTable.append(
|
||||||
$('<tr>').append([
|
$('<tr>').append([
|
||||||
$('<th>').text(container.Names[0]),
|
$('<th>').text(container.Names[0]),
|
||||||
|
|
@ -142,7 +142,7 @@ async function renderDash(data) {
|
||||||
])
|
])
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
dockerCard = $('<div>', {id: 'dockerinfo', class: 'terminal-card'}).append([
|
let dockerCard = $('<div>', {id: 'dockerinfo', class: 'terminal-card'}).append([
|
||||||
$('<header>').text('Kasm Docker containers'),
|
$('<header>').text('Kasm Docker containers'),
|
||||||
$('<table>').append(containersTable)
|
$('<table>').append(containersTable)
|
||||||
]);
|
]);
|
||||||
|
|
@ -150,7 +150,7 @@ async function renderDash(data) {
|
||||||
let usedmem = (info.mem.active/info.mem.total)*100;
|
let usedmem = (info.mem.active/info.mem.total)*100;
|
||||||
let totalmem = parseFloat(info.mem.total/1000000000).toFixed(2);
|
let totalmem = parseFloat(info.mem.total/1000000000).toFixed(2);
|
||||||
let diskbuffer = parseFloat(info.mem.buffcache/1000000000).toFixed(2);
|
let diskbuffer = parseFloat(info.mem.buffcache/1000000000).toFixed(2);
|
||||||
sysinfoTable = $('<tbody>').append([
|
let sysinfoTable = $('<tbody>').append([
|
||||||
$('<tr>').append([
|
$('<tr>').append([
|
||||||
$('<th>').text('CPU'),
|
$('<th>').text('CPU'),
|
||||||
$('<td>').text(info.cpu.vendor + ' ' + info.cpu.brand)
|
$('<td>').text(info.cpu.vendor + ' ' + info.cpu.brand)
|
||||||
|
|
@ -190,7 +190,7 @@ async function renderDash(data) {
|
||||||
)
|
)
|
||||||
])
|
])
|
||||||
]);
|
]);
|
||||||
systemCard = $('<div>', {id: 'systeminfo', class: 'terminal-card'}).append([
|
let systemCard = $('<div>', {id: 'systeminfo', class: 'terminal-card'}).append([
|
||||||
$('<header>').text('System Information'),
|
$('<header>').text('System Information'),
|
||||||
$('<table>').append(sysinfoTable)
|
$('<table>').append(sysinfoTable)
|
||||||
]);
|
]);
|
||||||
|
|
@ -231,7 +231,7 @@ async function pickSettings() {
|
||||||
$('<input>', {name: 'userPass', id: 'userPass', type: 'password', required: true, placeholder: 'required'})
|
$('<input>', {name: 'userPass', id: 'userPass', type: 'password', required: true, placeholder: 'required'})
|
||||||
]);
|
]);
|
||||||
let gpuOptions = [$('<option>', {value: 'disabled'}).text('Disabled')];
|
let gpuOptions = [$('<option>', {value: 'disabled'}).text('Disabled')];
|
||||||
for await (let card of Object.keys(gpus || {})) {
|
for (let card of Object.keys(gpus || {})) {
|
||||||
gpuOptions.push($('<option>', {value: card + '|' + gpus[card]}).text(card + ' - ' + gpus[card]));
|
gpuOptions.push($('<option>', {value: card + '|' + gpus[card]}).text(card + ' - ' + gpus[card]));
|
||||||
}
|
}
|
||||||
let forceGpu = $('<div>', {class: 'form-group'}).append([
|
let forceGpu = $('<div>', {class: 'form-group'}).append([
|
||||||
|
|
@ -298,8 +298,8 @@ function renderUpgrade() {
|
||||||
|
|
||||||
// Render image selection
|
// Render image selection
|
||||||
async function pickImages(upgrade) {
|
async function pickImages(upgrade) {
|
||||||
var installText;
|
let installText;
|
||||||
var installFunction;
|
let installFunction;
|
||||||
if (upgrade) {
|
if (upgrade) {
|
||||||
installText = 'Upgrade';
|
installText = 'Upgrade';
|
||||||
installFunction = 'upgrade()';
|
installFunction = 'upgrade()';
|
||||||
|
|
@ -311,7 +311,7 @@ async function pickImages(upgrade) {
|
||||||
titleChange('Image Selection');
|
titleChange('Image Selection');
|
||||||
let imagesDiv = $('<div>', {class: 'cardcontainer', id: 'images'});
|
let imagesDiv = $('<div>', {class: 'cardcontainer', id: 'images'});
|
||||||
$('#container').append(imagesDiv);
|
$('#container').append(imagesDiv);
|
||||||
for await (let image of images.images) {
|
for (let image of images.images) {
|
||||||
let imageName = $('<p>').text(image.friendly_name);
|
let imageName = $('<p>').text(image.friendly_name);
|
||||||
let imageDiv = $('<div>', {
|
let imageDiv = $('<div>', {
|
||||||
class: 'card',
|
class: 'card',
|
||||||
|
|
@ -382,8 +382,8 @@ function selectAll() {
|
||||||
|
|
||||||
// Show finished page
|
// Show finished page
|
||||||
function done(data) {
|
function done(data) {
|
||||||
var port = (typeof data === 'object') ? data.port : data;
|
const port = (typeof data === 'object') ? data.port : data;
|
||||||
var rollingTag = (typeof data === 'object') ? data.rollingTag : null;
|
const rollingTag = (typeof data === 'object') ? data.rollingTag : null;
|
||||||
showContainer();
|
showContainer();
|
||||||
titleChange('Complete');
|
titleChange('Complete');
|
||||||
let titleBar = $('<div>');
|
let titleBar = $('<div>');
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue