Skip to content
This repository has been archived by the owner on Dec 19, 2023. It is now read-only.

Commit

Permalink
Merge pull request #2 from 69/master
Browse files Browse the repository at this point in the history
Merging fix on-behalf of @69 (052-js-node-virtualbox).
  • Loading branch information
huntr-helper authored Apr 10, 2020
2 parents f0c7f78 + 8eeab16 commit 7221596
Showing 1 changed file with 52 additions and 55 deletions.
107 changes: 52 additions & 55 deletions lib/virtualbox.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

// @todo use a promise library instead of so many callbacks

var exec = require('child_process').exec,
var execFile = require('child_process').execFile,
host_platform = process.platform,
logging = require('./logging'),
vBoxManageBinary,
Expand All @@ -11,7 +11,9 @@ var exec = require('child_process').exec,
WINDOWS: 'windows',
MAC: 'mac',
LINUX: 'linux'
};
},
allowedBinaries = ['VBoxControl', vBoxManageBinary];



// Host operating system
Expand All @@ -33,14 +35,18 @@ if (/^win/.test(host_platform)) {

}

exec(vBoxManageBinary + ' --version', function(error, stdout, stderr) {
exec(vBoxManageBinary, ['--version'], function(error, stdout, stderr) {
// e.g., "4.3.38r106717" or "5.0.20r106931"
vbox_version = stdout.split(".")[0];
logging.info("Virtualbox version detected as %s", vbox_version);
});

function command(cmd, callback) {
exec(cmd, function(err, stdout, stderr) {
function command(bin, cmd, callback) {
if(!allowedBinaries.includes(bin)) {
throw new Error('Not an allowed binary');
}

execFile(bin, cmd, function(err, stdout, stderr) {

if (!err && stderr && cmd.indexOf("pause") !== -1 && cmd.indexOf("savestate") !== -1) {
err = new Error(stderr);
Expand All @@ -51,26 +57,26 @@ function command(cmd, callback) {
}

function vboxcontrol(cmd, callback) {
command('VBoxControl ' + cmd, callback);
command('VBoxControl', cmd, callback);
}

function vboxmanage(cmd, callback) {
command(vBoxManageBinary + cmd, callback);
command(vBoxManageBinary, cmd, callback);
}

function pause(vmname, callback) {
logging.info('Pausing VM "%s"', vmname);
vboxmanage('controlvm "' + vmname + '" pause', function(error, stdout) {
vboxmanage(['controlvm', vmname, 'pause'], function(error, stdout) {
callback(error);
});
}

function list(callback) {
logging.info('Listing VMs');
vboxmanage('list "runningvms"', function(error, stdout) {
vboxmanage(['list', 'runningvms'], function(error, stdout) {
var _list = {};
var _runningvms = parse_listdata(stdout);
vboxmanage('list "vms"', function(error, full_stdout) {
vboxmanage(['list', 'vms'], function(error, full_stdout) {
var _all = parse_listdata(full_stdout);
var _keys = Object.keys(_all);
for (var _i = 0; _i < _keys.length; _i += 1) {
Expand Down Expand Up @@ -111,29 +117,28 @@ function parse_listdata(raw_data) {

function reset(vmname, callback) {
logging.info('Resetting VM "%s"', vmname);
vboxmanage('controlvm "' + vmname + '" reset', function(error, stdout) {
vboxmanage(['controlvm', vmname, 'reset'], function(error, stdout) {
callback(error);
});
}

function resume(vmname, callback) {
logging.info('Resuming VM "%s"', vmname);
vboxmanage('controlvm "' + vmname + '" resume', function(error, stdout) {
vboxmanage(['controlvm', vmname, 'resume'], function(error, stdout) {
callback(error);
});
}

function start(vmname, use_gui, callback) {
var start_opts = ' --type ';
if ((typeof use_gui) === 'function') {
callback = use_gui;
use_gui = false;
}
start_opts += (use_gui ? 'gui' : 'headless');
var vmType = (use_gui ? 'gui' : 'headless');

logging.info('Starting VM "%s" with options: ', vmname, start_opts);
logging.info('Starting VM "%s" with options: ', vmname, vmType);

vboxmanage('-nologo startvm "' + vmname + '"' + start_opts, function(error, stdout) {
vboxmanage(['-nologo', 'startvm', vmname, '--type', vmType], function(error, stdout) {
if (error && /VBOX_E_INVALID_OBJECT_STATE/.test(error.message)) {
error = undefined;
}
Expand All @@ -143,7 +148,7 @@ function start(vmname, use_gui, callback) {

function stop(vmname, callback) {
logging.info('Stopping VM "%s"', vmname);
vboxmanage('controlvm "' + vmname + '" savestate', function(error, stdout) {
vboxmanage(['controlvm', vmname, 'savestate'], function(error, stdout) {
callback(error);
});
}
Expand All @@ -155,28 +160,28 @@ function savestate(vmname, callback) {

function vmExport(vmname, output, callback) {
logging.info('Exporting VM "%s"', vmname);
vboxmanage('export "' + vmname + '" --output "' + output + '"', function(error, stdout) {
vboxmanage(['export', vmname, '--output', output], function(error, stdout) {
callback(error);
});
}

function poweroff(vmname, callback) {
logging.info('Powering off VM "%s"', vmname);
vboxmanage('controlvm "' + vmname + '" poweroff', function(error, stdout) {
vboxmanage(['controlvm', vmname, 'poweroff'], function(error, stdout) {
callback(error);
});
}

function acpipowerbutton(vmname, callback) {
logging.info('ACPI power button VM "%s"', vmname);
vboxmanage('controlvm "' + vmname + '" acpipowerbutton', function(error, stdout) {
vboxmanage(['controlvm', vmname, 'acpipowerbutton'], function(error, stdout) {
callback(error);
});
}

function acpisleepbutton(vmname, callback) {
logging.info('ACPI sleep button VM "%s"', vmname);
vboxmanage('controlvm "' + vmname + '" acpisleepbutton', function(error, stdout) {
vboxmanage(['controlvm', vmname, 'acpisleepbutton'], function(error, stdout) {
callback(error);
});
}
Expand All @@ -199,18 +204,14 @@ function modify(vname, properties, callback) {
}
}

var cmd = 'modifyvm ' + args.map(function (arg) {
return '"' + arg + '"';
}).join(' ');

vboxmanage(cmd, function (error, stdout) {
vboxmanage(['modifyvm', ...args], function (error, stdout) {
callback(error);
});
}

function snapshotList(vmname, callback) {
logging.info('Listing snapshots for VM "%s"', vmname);
vboxmanage('snapshot "' + vmname + '" list --machinereadable', function(error, stdout) {
vboxmanage(['snapshot', vmname, 'list', '--machinereadable'], function(error, stdout) {

if (error) {
callback(error);
Expand Down Expand Up @@ -255,14 +256,15 @@ function snapshotTake(vmname, name, /*optional*/ description, /*optional*/ live,
live = false;
}

var cmd = 'snapshot ' + JSON.stringify(vmname) + ' take ' + JSON.stringify(name);
var cmd = ['snapshot', vmname, 'take', name];

if(description) {
cmd += ' --description ' + JSON.stringify(description);
cmd.push('--description');
cmd.push(description);
}

if(live === true) {
cmd += ' --live';
cmd.push('--live');
}

vboxmanage(cmd, function(error, stdout) {
Expand All @@ -276,19 +278,16 @@ function snapshotTake(vmname, name, /*optional*/ description, /*optional*/ live,

function snapshotDelete(vmname, uuid, callback) {
logging.info('Deleting snapshot "%s" for VM "%s"', uuid, vmname);
var cmd = 'snapshot ' + JSON.stringify(vmname) + ' delete ' + JSON.stringify(uuid);
vboxmanage(cmd, callback);
vboxmanage(['snapshot', vmname, 'delete', uuid], callback);
}

function snapshotRestore(vmname, uuid, callback) {
logging.info('Restoring snapshot "%s" for VM "%s"', uuid, vmname);
var cmd = 'snapshot ' + JSON.stringify(vmname) + ' restore ' + JSON.stringify(uuid);
vboxmanage(cmd, callback);
vboxmanage(['snapshot', vmname, 'restore', uuid], callback);
}

function isRunning(vmname, callback) {
var cmd = 'list runningvms';
vboxmanage(cmd, function (error, stdout) {
vboxmanage(['list', 'runningvms'], function (error, stdout) {
logging.info('Checking virtual machine "%s" is running or not', vmname);
if (stdout.indexOf(vmname) === -1) {
callback(error, false);
Expand All @@ -308,7 +307,7 @@ function keyboardputscancode(vmname, codes, callback) {
return s;
}).join(' ');
logging.info('Sending VM "%s" keyboard scan codes "%s"', vmname, codeStr);
vboxmanage('controlvm "' + vmname + '" keyboardputscancode ' + codeStr, function(error, stdout) {
vboxmanage(['controlvm', vmname, 'keyboardputscancode', codeStr], function(error, stdout) {
callback(error, stdout);
});
}
Expand All @@ -332,28 +331,29 @@ function vmExec(options, callback) {
guestproperty.os(vm, getOSTypeCb);

function getOSTypeCb(os_type) {
var cmd = 'guestcontrol "' + vm + '"';
var runcmd = ' execute --image ';

if (vbox_version == 5) {
runcmd = ' run ';
}

var cmd = ['guestcontrol', vm];
var runcmd = vbox_version == 5 ? ['run'] : ['execute', '--image'];
cmd.push(runcmd);
switch (os_type) {
case known_OS_types.WINDOWS:
path = path.replace(/\\/g, '\\\\');
cmd += runcmd + ' "cmd.exe" --username ' + username + (password ? ' --password ' + password : '') + ' -- "/c" "' + path + '" "' + params + '"';
cmd.push('cmd.exe', '--username', username);
break;
case known_OS_types.MAC:
cmd += runcmd + ' "/usr/bin/open -a" --username ' + username + (password ? ' --password ' + password : '') + ' -- "/c" "' + path + '" "' + params + '"';
cmd.push('/usr/bin/open', '-a', '--username', username);
break;
case known_OS_types.LINUX:
cmd += runcmd + ' "/bin/sh" --username ' + username + (password ? ' --password ' + password : '') + ' -- "/c" "' + path + '" "' + params + '"';
cmd.push('/bin/sh', '--username', username);
break;
default:
break;
}

if (password) {
cmd.push('--password', password);
}
cmd.push('--', '/c', path, params);

logging.info('Executing command "vboxmanage %s" on VM "%s" detected OS type "%s"', cmd, vm, os_type);

vboxmanage(cmd, function(error, stdout) {
Expand All @@ -367,8 +367,7 @@ function vmKill(options, callback) {
options = options || {};
var vm = options.vm || options.name || options.vmname || options.title,
path = options.path || options.cmd || options.command || options.exec || options.execute || options.run,
image_name = options.image_name || path,
cmd = 'guestcontrol "' + vm + '" process kill';
image_name = options.image_name || path;

guestproperty.os(vm, function(os_type) {
switch (os_type) {
Expand Down Expand Up @@ -404,9 +403,8 @@ var guestproperty = {

guestproperty.os(vm, getOSTypeCallback);

function getOSTypeCallback(os_type) {
var cmd = 'guestproperty get "' + vm + '" ' + key;
vboxmanage(cmd, function(error, stdout) {
function gvboxmanageetOSTypeCallback(os_type) {
vboxmanage(['guestproperty', 'get', vm, key], function(error, stdout) {
if (error) {
throw error;
}
Expand Down Expand Up @@ -445,7 +443,7 @@ var guestproperty = {
}

try {
exec(vBoxManageBinary + 'showvminfo -machinereadable "' + vmname + '"', getOSTypeCallback);
vboxmanage('showvminfo', '--machinereadable', vmname, getOSTypeCallback);
} catch (e) {
logging.info('Could not showvminfo for %s', vmname);
}
Expand All @@ -459,8 +457,7 @@ var extradata = {
key = options.key,
value = options.defaultValue || options.value;

var cmd = 'getextradata "' + vm + '" "' + key + '"';
vboxmanage(cmd, function(error, stdout) {
vboxmanage(['getextradata', vm, key], function(error, stdout) {
if (error) {
callback(error);
return;
Expand Down

0 comments on commit 7221596

Please sign in to comment.