virtualbox的命令行可以让我们快速便捷的实现一些Virtualbox基本的操作,例如创建虚拟机、启动虚拟机以及关闭虚拟机等。与此同时,Virtualbox的SDK还为我们实现了Webservice服务(如下图所示),使我们可以用各种语言,如python和java等来调用一些Virtualbox底层(sdk)的Api。命令行的操作,简单易懂,网上资料也很多。但是对于通过java的api来实现对webserive服务的调用,很多人在看到提供的大量Api的时候往往感到无从下手,不知道需要调用哪些Ap去满足自己的开发需求。下面将对Virtualbox的一些基本操作的命令行与java.virtualbox的jar提供的接口进行对照分析,希望大家能快速的使用java来实现一些Virtualbox的基础功能。
一、环境支持
1、命令行
运行cmd,进入Virtualbox的安装目录下,即可在cmd下输入相关命令实现功能。
2、WebService
(1)运行cmd,进入Virtualbox的安装目录。
(2)设置web服务认证库为null,在安装目录下执行:
vboxmanage setproperty websrvauthlibrary null
(3)置vrdp的认证方式为简单,即通过用户名和密码来认证:
vboxmanage setproperty vrdeauthlibrary "VBoxAuthSimple"
(4)开启web服务:
vboxwebsrv --host 127.0.0.1
(5)在maven项目中引入所需jar包
<dependency>
<groupId>org.virtualbox</groupId>
<artifactId>vboxjws</artifactId>
<version>4.2.8</version>
</dependency>
二、对比分析
1、验证服务是否开启
String vm_inner_host = "127.0.0.1"
try{
VirtualBoxManager vbm = VirtualBoxManager.createInstance(null);
vbm.connect("http://" + vm_inner_host + ":18083", "", "");
} catch (VBoxException e) {
Log.error(this, "initVbm", "VirtualBoxManager 连接 "+ vm_inner_host +":18083 失败");
e.printStackTrace();
}
2、创建并注册虚拟机
//VirtualBox命令行实现,创建名为machine_test的虚拟机
VBoxManage createvm --name machine_test --register
//WebService实现
IMachine machine;
List<String> list =new ArrayList<String>();
machine = vbm.getVBox().createMachine("", "machine_test",list, "", "");
3、设置系统类型
//VirtualBox命令行实现,将系统烈性设置为Unbuntu 64位
VBoxManage modifyvm machine_test --ostype Ubuntu_64
//WebService实现
machine.setOSTypeId("Ubuntu_64");
4、设置内存大小
//VirtualBox命令行实现,将内存设置为4GB
VBoxManage modifyvm machine_test --memory 4096
//WebService实现
machine.setMemorySize(Long.valueOf("4096"));
5、创建存储控制器
//命令行实现,创建IDE/STAT存储控制器
VBoxManage storagectl UbuntuRDHome --name IDE --add ide
VBoxManage storagectl UbuntuRDHome --name SATA --add sata
//WebService实现
machine.addStorageController("IDE", StorageBus.IDE);
machine.addStorageController("STAT", StorageBus.SATA);
6、关联镜像文件
//命令行实现
VBoxManage storageattach UbuntuRDHome --storagectl IDE --port 0 --device 0 --type dvddrive --medium ubuntu-16.04.3-server-amd64.iso
//WebService实现(必须已经建立IDE存储器)
//value为镜像文件的地址
value = "ubuntu-16.04.3-server-amd64.iso"
IMedium iMedium = vbm.getVBox().openMedium(value,DeviceType.DVD,AccessMode.ReadOnly, Boolean.FALSE)
//为虚拟机添加设备
machine.attachDeviceWithoutMedium("IDE",0, 1, DeviceType.DVD);
//虚拟机挂载镜像
machine.mountMedium("IDE", 0, 1, iMedium, true);
7、虚拟机管理
//命令行实现虚拟机启动和关闭
//启动
VBoxManage startvm machine_test
//关闭
VBoxManage controlvm UbuntuRDHome poweroff
//WebService实现
//启动
Progress progress;
session = vbm.getSessionObject();
progress = machine.launchVMProcess(session, "gui", "");
IProgress progress = session.getConsole().powerDown();
8、案列源码
private final Logger LOGGER = LogManager.getLogger(VBoxControlUtil.class);
private IMachine machine;
private VirtualBoxManager vbm;
private ISession session;
private String vboxName;
String vm_inner_host = "127.0.0.1";
public VBoxControlUtil() {
vbm = VirtualBoxManager.createInstance(null);
vbm.connect("http://" + vm_inner_host + ":18083","","");
session = vbm.getSessionObject();
}
public VBoxControlUtil(String vmname) throws Exception {
LOGGER.info("begin connect :"+ vmname);
vboxName = vmname;
vbm = VirtualBoxManager.createInstance(null);
vbm.connect("http://" + vm_inner_host + ":18083","","");
if(vboxName!=null){
IVirtualBox vbox = vbm.getVBox();
machine = vbox.findMachine(vmname);
}
session = vbm.getSessionObject();
LOGGER.info("conect sucess : " + vmname);
}
public synchronized void disconnect(VirtualBoxManager manager) {
try {
manager.disconnect();
} catch (VBoxException e) {
}
}
public synchronized boolean isConnected(VirtualBoxManager manager) {
try {
manager.getVBox().getVersion();
return true;
} catch (VBoxException e) {
return false;
}
}
public synchronized boolean createMachine(String machineName){
List<String> list =new ArrayList<String>();
machine = vbm.getVBox().createMachine("", machineName,list, "", "");
machine.setOSTypeId("Ubuntu");
machine.setMemorySize(Long.valueOf("4096"));
machine.addStorageController("IDE", StorageBus.IDE);
machine.addStorageController("STAT", StorageBus.SATA);
machine.setBootOrder(Long.valueOf("1"),DeviceType.DVD);
machine.setBootOrder(Long.valueOf("2"), DeviceType.HardDisk);
vbm.getVBox().registerMachine(machine);
return true;
}
@SuppressWarnings({ "unchecked", "rawtypes" })
public synchronized long startVm() {
if (null == machine) {
LOGGER.error("Cannot find machine name is : " + vboxName);
return -1;
}
MachineState state = machine.getState();
if (MachineState.Running == state || MachineState.PoweredOff != state) {
long rs = stopVm();
if(rs == -1){
return -1;
}
}
IProgress progress;
String env = "";
long result = 0;
try {
progress = machine.launchVMProcess(session, "gui", env);
if (!waitProgressCompletion(progress)) {
LOGGER.warn("Cannot run Vbox!");
return -1;
}
} catch (Exception e) {
e.printStackTrace();
LOGGER.error(" start virtualbox is error : " + e.getMessage());
return -1;
}
IConsole iCon = session.getConsole();
IGuest iGuest = iCon.getGuest();
IGuestSession igs = iGuest.createSession("Administrator", "mima",
"", "");
List lArgs = new ArrayList();
lArgs.add("/K c://bin//update.bat "+vm_inner_host+" "+"18083");
List lFlags = new ArrayList();
lFlags.add(ProcessCreateFlag.WaitForStdOut);
lFlags.add(ProcessCreateFlag.WaitForStdErr);
IGuestProcess igp = igs.processCreate("c://windows//system32//cmd.exe",
lArgs, null, lFlags, (long) 120000);
List lWaitFlags = new ArrayList();
lWaitFlags.add(ProcessWaitForFlag.Start);
ProcessWaitResult rlt = igp.waitForArray(lWaitFlags, (long) 120 * 1000);
if (rlt == ProcessWaitResult.Start) {
ProcessStatus ps = igp.getStatus();
if (ps == ProcessStatus.Started) {
LOGGER.info("runProcess is success");
}
}
igs.close();
return result;
}
public synchronized long stopVm() {
if (null == machine) {
LOGGER.error("Cannot find machine: " + vboxName);
return -1;
}
long result = 0;
MachineState state = machine.getState();
try {
if (MachineState.PoweredOff != state) {
if(MachineState.Running == state){
if(session.getState() == SessionState.Locked){
session.unlockMachine();
}
machine.lockMachine(session, LockType.Shared);
}
IProgress progress = session.getConsole().powerDown();
progress.waitForCompletion(10000);
result = progress.getResultCode();
if (0 != result) {
LOGGER.error("machine " + vboxName + " error: "
+ getVBProcessError(progress));
return -1;
} else {
LOGGER.info("machine " + vboxName + " stopped");
}
}
while(session.getState() == SessionState.Locked){
Thread.sleep(500);
}
machine.lockMachine(session, LockType.Shared);
ISnapshot iSnap = machine.getCurrentSnapshot();
IConsole iCon = session.getConsole();
IProgress iProg = iCon.restoreSnapshot(iSnap);
if (!waitProgressCompletion(iProg)) {
LOGGER.warn("Cannot restoreSnapshot VM!");
}
LOGGER.info("restoreSnapshot " + vboxName + "sucessed");
} catch (Exception e) {
e.printStackTrace();
LOGGER.error("restoreSnapshot is error : " + e.getMessage());
return -1;
} finally {
session.unlockMachine();
}
return result;
}
private String getVBProcessError(IProgress progress) {
if (0 == progress.getResultCode()) {
return "";
}
StringBuilder sb = new StringBuilder("");
IVirtualBoxErrorInfo errInfo = progress.getErrorInfo();
while (null != errInfo) {
sb.append(errInfo.getText());
sb.append("/n");
errInfo = errInfo.getNext();
}
return sb.toString();
}
private boolean waitProgressCompletion(IProgress iProg) {
iProg.waitForCompletion(10000);
if (iProg.getResultCode() != 0)
return false;
return true;
}
//改变内存大小
public void setMemorySize(VBoxControlUtil self,String value) throws Exception{
IMachine machine = self.machine;
System.out.println(self.session.getState());
machine.lockMachine(self.session, LockType.Shared);
System.out.println(self.session.getState());
IMachine mutable = self.session.getMachine();
mutable.setMemorySize(Long.valueOf(value));
mutable.saveSettings();
self.session.unlockMachine();
}
//设置系统类型Id
public void setOsTypeId(VBoxControlUtil self,String value){
IMachine machine = self.machine;
System.out.println(self.session.getState());
machine.lockMachine(self.session, LockType.Shared);
System.out.println(self.session.getState());
IMachine mutable = self.session.getMachine();
mutable.setOSTypeId(value);
mutable.saveSettings();
self.session.unlockMachine();
}
//关联镜像
public void mountMedium(VBoxControlUtil self,String value){
IMachine machine = self.machine;
IMedium iMedium = self.vbm.getVBox().openMedium(value,DeviceType.DVD,AccessMode.ReadOnly, Boolean.FALSE);
machine.lockMachine(self.session, LockType.Shared);
IMachine mutable = self.session.getMachine();
mutable.attachDeviceWithoutMedium("IDE",0, 1, DeviceType.DVD);
mutable.mountMedium("IDE", 0, 1, iMedium, true);
mutable.saveSettings();
self.session.unlockMachine();
self.disconnect(self.vbm);
}
//关联虚拟磁盘
public void mountVdi(VBoxControlUtil self,String value){
IMachine machine = self.machine;
IMedium iMedium = self.vbm.getVBox().openMedium(value,DeviceType.HardDisk,AccessMode.ReadWrite, Boolean.TRUE);
machine.lockMachine(self.session, LockType.Shared);
IMachine mutable = self.session.getMachine();
mutable.attachDeviceWithoutMedium("IDE",1, 0, DeviceType.HardDisk);
mutable.mountMedium("IDE", 1, 0, iMedium, true);
mutable.saveSettings();
self.session.unlockMachine();
self.disconnect(self.vbm);
}