Security News
RubyGems.org Adds New Maintainer Role
RubyGems.org has added a new "maintainer" role that allows for publishing new versions of gems. This new permission type is aimed at improving security for gem owners and the service overall.
virtualbox
Advanced tools
A JavaScript library to interact with VirtualBox virtual machines.
Obtain the package
$ npm install virtualbox [--save] [-g]
and then use it
var virtualbox = require('virtualbox');
The general formula for commands is:
virtualbox. API command ( "registered vm name", [parameters], callback );
Available API commands are listed at the end of this document.
node-virtualbox
provides convenience methods to command the guest machine's power state in the customary ways.
Virtual machines will start headless by default, but you can pass a boolean parameter to start them with a GUI:
virtualbox.start('machine_name', true, function start_callback(error) {
if (error) throw error;
console.log('Virtual Machine has started WITH A GUI!');
});
So as not to break pre-0.1.0 implementations, the old method still works (which also defaults to headless):
virtualbox.start('machine_name', function start_callback(error) {
if (error) throw error;
console.log('Virtual Machine has started HEADLESS!');
});
Note: For historical reasons, .stop
is an alias to .savestate
.
virtualbox.stop('machine_name', function stop_callback(error) {
if (error) throw error;
console.log('Virtual Machine has been saved');
});
To halt a machine completely, you can use poweroff
or acpipowerbutton
:
virtualbox.poweroff('machine_name', function poweroff_callback(error) {
if (error) throw error;
console.log('Virtual Machine has been powered off!');
});
virtualbox.acpipowerbutton('machine_name', function acpipower_callback(error) {
if (error) throw error;
console.log("Virtual Machine's ACPI power button was pressed.");
});
Noting the caveat above that .stop
is actually an alias to .savestate
...
virtualbox.pause('machine_name', function pause_callback(error) {
if (error) throw error;
console.log('Virtual Machine is now paused!');
});
virtualbox.savestate('machine_name', function save_callback(error) {
if (error) throw error;
console.log('Virtual Machine is now paused!');
});
And, in the same family, acpisleepbutton
:
virtualbox.acpisleepbutton('machine_name', function acpisleep_callback(error) {
if (error) throw error;
console.log("Virtual Machine's ACPI sleep button signal was sent.");
});
Note that you should probably resume a machine which is in one of the above three states.
virtualbox.resume('machine_name', function resume_callback(error) {
if (error) throw error;
console.log('Virtual Machine is now paused!');
});
And, of course, a reset button method:
virtualbox.reset('machine_name', function reset_callback(error) {
if (error) throw error;
console.log("Virtual Machine's reset button was pressed!");
});
You can export with export
method:
virtualbox.export('machine_name', 'output', function export_callback(error) {
if (error) throw error;
console.log('Virtual Machine was exported!');
});
You can show snapshot list with snapshotList
method:
virtualbox.snapshotList('machine_name', function (
error,
snapshotList,
currentSnapshotUUID
) {
if (error) throw error;
if (snapshotList) {
console.log(
JSON.stringify(snapshotList),
JSON.stringify(currentSnapshotUUID)
);
}
});
And, you can take a snapshot:
virtualbox.snapshotTake('machine_name', 'snapshot_name', function (
error,
uuid
) {
if (error) throw error;
console.log('Snapshot has been taken!');
console.log('UUID: ', uuid);
});
Or, delete a snapshot:
virtualbox.snapshotDelete('machine_name', 'snapshot_name', function (error) {
if (error) throw error;
console.log('Snapshot has been deleted!');
});
Or, restore a snapshot:
virtualbox.snapshotRestore('machine_name', 'snapshot_name', function (error) {
if (error) throw error;
console.log('Snapshot has been restored!');
});
Make a full clone (duplicate virtual hard drive) of a machine:
virtualbox.clone('source_machine_name', 'new_machine_name', function (error) {
if (error) throw error;
console.log('Done fully cloning the virtual machine!');
});
Make a linked clone (interdependent-differentially stored virtual hard drive) of a machine:
virtualbox.snapshotTake('machine_name', 'snapshot_name', function (
error,
uuid
) {
if (error) throw error;
console.log('Snapshot has been taken!');
console.log('UUID: ', uuid);
virtualbox.clone(
'machine_name',
'new_machine_name',
'snapshot_name',
function (error) {
if (error) throw error;
console.log('Done making a linked clone of the virtual machine!');
}
);
});
In case the VM doesn't have an IDE controller you can use the storagectl command to add one:
virtualbox.storage.addCtl(
{
vm: 'machine_name',
perhiperal_name: 'IDE', //optional
type: 'ide', //optional
},
function () {
console.log('Controller has been added!');
}
);
Mount an ISO file to the added controller:
virtualbox.storage.attach(
{
vm: 'machine_name',
perhiperal_name: 'IDE', //optional
port: '0', //optional
device: '0', //optional
type: 'dvddrive', //optional
medium: 'X:Foldercontaining\the.iso',
},
function () {
console.log('Image has been mounted!');
}
);
The medium parameter of the options object can be set to the none value to unmount.
node-virtualbox
is not opinionated: we believe that you know best what you need to do with your virtual machine. Maybe that includes issuing sudo rm -rf /
for some reason.
To that end, the virtualbox
APIs provided by this module take absolutely no steps to prevent you shooting yourself in the foot.
:warning: Therefore, if you accept user input and pass it to the virtual machine, you should take your own steps to filter input before it gets passed to virtualbox
.
For more details and discussion, see issue #29.
This method takes an options object with the name of the virtual machine, the path to the binary to be executed and any parameters to pass:
var options = {
vm: 'machine_name',
cmd: 'C:\\Program Files\\Internet Explorer\\iexplore.exe',
params: 'https://google.com',
};
virtualbox.exec(options, function exec_callback(error, stdout) {
if (error) throw error;
console.log('Started Internet Explorer...');
});
Pass username and password information in an options
object:
var options = {
vm: 'machine_name',
user: 'Administrator',
password: '123456',
cmd: 'C:\\Program Files\\Internet Explorer\\iexplore.exe',
params: 'https://google.com',
};
Tasks can be killed in the guest as well. In Windows guests this calls taskkill.exe /im
and on Linux, BSD and OS X (Darwin) guests, it calls sudo killall
:
virtualbox.kill(
{
vm: 'machine_name',
cmd: 'iexplore.exe',
},
function kill_callback(error) {
if (error) throw error;
console.log('Terminated Internet Explorer.');
}
);
Keyboard scan code sequences can be piped directly to a virtual machine's console:
var SCAN_CODES = virtualbox.SCAN_CODES;
var sequence = [
{ key: 'SHIFT', type: 'make', code: SCAN_CODES['SHIFT'] },
{ key: 'A', type: 'make', code: SCAN_CODES['A'] },
{ key: 'SHIFT', type: 'break', code: SCAN_CODES.getBreakCode('SHIFT') },
{ key: 'A', type: 'break', code: SCAN_CODES.getBreakCode('A') },
];
virtualbox.keyboardputscancode(
'machine_name',
sequence,
function keyscan_callback(err) {
if (error) throw error;
console.log('Sent SHIFT A');
}
);
List all registered machines, returns an array:
virtualbox.list(function list_callback(machines, error) {
if (error) throw error;
// Act on machines
});
Obtaining a guest property by key name:
var options = {
vm: 'machine_name',
key: '/VirtualBox/GuestInfo/Net/0/V4/IP',
};
virtualbox.guestproperty.get(function guestproperty_callback(machines, error) {
if (error) throw error;
// Act on machines
});
Obtaining an extra property by key name:
var options = {
vm: 'machine_name',
key: 'GUI/Fullscreen',
};
virtualbox.extradata.get(options, function extradataget_callback(error, value) {
if (error) throw error;
console.log(
'Virtual Machine "%s" extra "%s" value is "%s"',
options.vm,
options.key,
value
);
});
Writing an extra property by key name:
var options = {
vm: 'machine_name',
key: 'GUI/Fullscreen',
value: 'true',
};
virtualbox.extradata.set(options, function extradataset_callback(error) {
if (error) throw error;
console.log(
'Set Virtual Machine "%s" extra "%s" value to "%s"',
options.vm,
options.key,
options.value
);
});
Note: some properties are only available/effective if the Guest OS has the (https://www.virtualbox.org/manual/ch04.html)[Guest Additions] installed and running.
var virtualbox = require('virtualbox');
virtualbox.start('machine_name', function start_callback(error) {
if (error) throw error;
console.log('VM "w7" has been successfully started');
virtualbox.exec(
{
vm: 'machine_name',
cmd: 'C:\\Program Files\\Internet Explorer\\iexplore.exe',
params: 'http://google.com',
},
function (error) {
if (error) throw error;
console.log('Running Internet Explorer...');
}
);
});
virtualbox
.pause({vm:"machine_name"}, callback)
.reset({vm:"machine_name"}, callback)
.resume({vm:"machine_name"}, callback)
.start({vm:"machine_name"}, callback)
and .start({vm:"machine_name"}, true, callback)
.stop({vm:"machine_name"}, callback)
.savestate({vm:"machine_name"}, callback)
.export({vm:"machine_name"}, {output: "output"}, callback)
.poweroff({vm:"machine_name"}, callback)
.acpisleepbutton({vm:"machine_name"}, callback)
.acpipowerbutton({vm:"machine_name"}, callback)
.guestproperty.get({vm:"machine_name", property: "propname"}, callback)
.exec(){vm: "machine_name", cmd: "C:\\Program Files\\Internet Explorer\\iexplore.exe", params: "http://google.com"}, callback)
.exec(){vm: "machine_name", user:"Administrator", password: "123456", cmd: "C:\\Program Files\\Internet Explorer\\iexplore.exe", params: "http://google.com"}, callback)
.keyboardputscancode("machine_name", [scan_codes], callback)
.kill({vm:"machine_name"}, callback)
.list(callback)
.isRunning({vm:"machine_name"}, callback)
.snapshotList({vm:"machine_name"}, callback)
.snapshotTake({vm:"machine_name"}, {vm:"snapshot_name"}, callback)
.snapshotDelete({vm:"machine_name"}, {vm:"snapshot_UUID"}, callback)
.snapshotRestore({vm:"machine_name"}, {vm:"snapshot_UUID"}, callback)
.clone({vm:"machine_name"}, {vm:"new_machine_name"}, callback)
.storage.addCtl({vm: "machine_name", perhiperal_name: "IDE", type: "ide"}, callback)
.storage.attach({vm: "machine_name", perhiperal_name: "IDE", port: "0", device: "0", type: "dvddrive", medium: "X:\Folder\containing\the.iso"}, callback)
.extradata.get({vm:"machine_name", key:"keyname"}, callback)
.extradata.set({vm:"machine_name", key:"keyname", value:"val"}, callback)
sudo
with NOPASSWD
(at least for now).vboxmanage
not the actual running state/runlevel of services within the guest. See https://github.com/Node-Virtualization/node-virtualbox/issues/9Please do!
Please abide by the Contributor Code of Conduct.
We currently do not have a complete unit testing suite. However, example scripts and a Vagrantfile are provided. Test your changes by writing a new script and/or running through all the test scripts to make sure they behave as expected. To do this install vagrant and run vagrant up
in this repository's root directory. Then run the example scripts by using node: node test/integration/<script-name>.js
. Please be ready to provide test output upon opening a pull request.
FAQs
A library to interact with VirtualBox.
We found that virtualbox demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 2 open source maintainers collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
RubyGems.org has added a new "maintainer" role that allows for publishing new versions of gems. This new permission type is aimed at improving security for gem owners and the service overall.
Security News
Node.js will be enforcing stricter semver-major PR policies a month before major releases to enhance stability and ensure reliable release candidates.
Security News
Research
Socket's threat research team has detected five malicious npm packages targeting Roblox developers, deploying malware to steal credentials and personal data.