Skip to content

Repository files navigation

node-virtualbox

NPM versionBuild Status

DepShield Badgedavid-dm badge

A JavaScript library to interact with VirtualBox virtual machines.

Table of Contents

Installation

Obtain the package

$ npm install virtualbox [--save] [-g]

and then use it

varvirtualbox=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.

Controlling Power and State

node-virtualbox provides convenience methods to command the guest machine's power state in the customary ways.

Starting a cold machine: Two 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,functionstart_callback(error){if(error)throwerror;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",functionstart_callback(error){if(error)throwerror;console.log("Virtual Machine has started HEADLESS!");});

Stopping a machine

Note: For historical reasons, .stop is an alias to .savestate.

virtualbox.stop("machine_name",functionstop_callback(error){if(error)throwerror;console.log("Virtual Machine has been saved");});

To halt a machine completely, you can use poweroff or acpipowerbutton:

virtualbox.poweroff("machine_name",functionpoweroff_callback(error){if(error)throwerror;console.log("Virtual Machine has been powered off!");});
virtualbox.acpipowerbutton("machine_name",functionacpipower_callback(error){if(error)throwerror;console.log("Virtual Machine's ACPI power button was pressed.");});

Pausing, Saving and Resuming a machine

Noting the caveat above that .stop is actually an alias to .savestate...

virtualbox.pause("machine_name",functionpause_callback(error){if(error)throwerror;console.log("Virtual Machine is now paused!");});
virtualbox.savestate("machine_name",functionsave_callback(error){if(error)throwerror;console.log("Virtual Machine is now paused!");});

And, in the same family, acpisleepbutton:

virtualbox.acpisleepbutton("machine_name",functionacpisleep_callback(error){if(error)throwerror;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",functionresume_callback(error){if(error)throwerror;console.log("Virtual Machine is now paused!");});

And, of course, a reset button method:

virtualbox.reset("machine_name",functionreset_callback(error){if(error)throwerror;console.log("Virtual Machine's reset button was pressed!");});

Export a machine

You can export with export method:

virtualbox.export("machine_name","output",functionexport_callback(error){if(error)throwerror;console.log("Virtual Machine was exported!");});

Snapshot Manage

You can show snapshot list with snapshotList method:

virtualbox.snapshotList("machine_name",function(error,snapshotList,currentSnapshotUUID){if(error)throwerror;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)throwerror;console.log('Snapshot has been taken!');console.log('UUID: ',uuid);});

Or, delete a snapshot:

virtualbox.snapshotDelete("machine_name","snapshot_name",function(error){if(error)throwerror;console.log('Snapshot has been deleted!');});

Or, restore a snapshot:

virtualbox.snapshotRestore("machine_name","snapshot_name",function(error){if(error)throwerror;console.log('Snapshot has been restored!');});

Cloning VMs

Make a full clone (duplicate virtual hard drive) of a machine:

virtualbox.clone("source_machine_name","new_machine_name",function(error){if(error)throwerror;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)throwerror;console.log('Snapshot has been taken!');console.log('UUID: ',uuid);virtualbox.clone("machine_name","new_machine_name","snapshot_name",function(error){if(error)throwerror;console.log('Done making a linked clone of the virtual machine!');});});

Storage

Manage the IDE controller

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",//optionaltype: "ide"//optional},function(){console.log('Controller has been added!');})

Attach a disk image file

Mount an ISO file to the added controller:

virtualbox.storage.attach({vm: "machine_name",perhiperal_name: "IDE",//optionalport: "0",//optionaldevice: "0",//optionaltype: "dvddrive",//optionalmedium: "X:\Folder\containing\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.

Controlling the guest OS

A note about security ⚠️

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.

⚠️ 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.

Running programs in the guest

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:

varoptions={vm: "machine_name",cmd: "C:\\Program Files\\Internet Explorer\\iexplore.exe",params: "https://google.com"}virtualbox.exec(options,functionexec_callback(error,stdout){if(error)throwerror;console.log('Started Internet Explorer...');});

Executing commands as Administrators on Windows guests

Pass username and password information in an options object:

varoptions={vm: "machine_name",user:"Administrator",password: "123456",cmd: "C:\\Program Files\\Internet Explorer\\iexplore.exe",params: "https://google.com"};

Killing programs in the guest

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"},functionkill_callback(error){if(error)throwerror;console.log('Terminated Internet Explorer.');});

Sending keystrokes to a virtual machine

Keyboard scan code sequences can be piped directly to a virtual machine's console:

varSCAN_CODES=virtualbox.SCAN_CODES;varsequence=[{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,functionkeyscan_callback(err){if(error)throwerror;console.log('Sent SHIFT A');});

Meta information about machine

List all registered machines, returns an array:

virtualbox.list(functionlist_callback(machines,error){if(error)throwerror;// Act on machines});

Obtaining a guest property by key name:

varoptions={vm: "machine_name",key: "/VirtualBox/GuestInfo/Net/0/V4/IP"}virtualbox.guestproperty.get(functionguestproperty_callback(machines,error){if(error)throwerror;// Act on machines});

Obtaining an extra property by key name:

varoptions={vm: "machine_name",key: "GUI/Fullscreen"}virtualbox.extradata.get(options,functionextradataget_callback(error,value){if(error)throwerror;console.log('Virtual Machine "%s" extra "%s" value is "%s"',options.vm,options.key,value);});

Writing an extra property by key name:

varoptions={vm: "machine_name",key: "GUI/Fullscreen",value: "true"}virtualbox.extradata.set(options,functionextradataset_callback(error){if(error)throwerror;console.log('Set Virtual Machine "%s" extra "%s" value to "%s"',options.vm,options.key,options.value);});

Putting it all together

varvirtualbox=require('virtualbox');virtualbox.start("machine_name",functionstart_callback(error){if(error)throwerror;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)throwerror;console.log('Running Internet Explorer...');});});

Available Methods

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)
  • .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)

Troubleshooting

  • Make sure that Guest account is enabled on the VM.
  • Make sure your linux guest can sudo with NOPASSWD (at least for now).
  • VMs start headlessly by default: if you're having trouble with executing a command, start the VM with GUI and observe the screen after executing same command.
  • To avoid having "Concurrent guest process limit is reached" error message, execute your commands as an administrator.
  • Don't forget that this whole thing is asynchronous, and depends on the return of vboxmanagenot the actual running state/runlevel of services within the guest. See Node-Virtualization#9

More Examples

License

MIT

Contributing

Please do!

Please abide by the Contributor Code of Conduct.

About

A JavaScript Library for Interacting with VirtualBox

Resources

Code of conduct

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages