diff --git a/gns3server/modules/attic.py b/gns3server/modules/attic.py index fa31e50e..cdfcc050 100644 --- a/gns3server/modules/attic.py +++ b/gns3server/modules/attic.py @@ -50,6 +50,7 @@ def find_unused_port(start_port, end_port, host='127.0.0.1', socket_type="TCP", else: socket_type = socket.SOCK_STREAM + last_exception = None for port in range(start_port, end_port + 1): if port in ignore_ports: continue @@ -63,15 +64,16 @@ def find_unused_port(start_port, end_port, host='127.0.0.1', socket_type="TCP", s.bind((host, port)) # the port is available if bind is a success return port except OSError as e: - if e.errno == errno.EADDRINUSE: # socket already in use + last_exception = e + if e.errno == errno.EADDRINUSE or e.errno == errno.EACCES: # socket already in use or permission denied if port + 1 == end_port: break else: continue else: - raise Exception("Could not find an unused port: {}".format(e)) + raise Exception("Could not find an unused port between {} and {} on host {}: {}".format(start_port, end_port, host, e)) - raise Exception("Could not find a free port between {0} and {1}".format(start_port, end_port)) + raise Exception("Could not find a free port between {} and {} on host {}, last exception: {}".format(start_port, end_port, host, last_exception)) def wait_socket_is_ready(host, port, wait=2.0, socket_timeout=10): diff --git a/gns3server/modules/virtualbox/__init__.py b/gns3server/modules/virtualbox/__init__.py index 0d2a97fc..114563dd 100644 --- a/gns3server/modules/virtualbox/__init__.py +++ b/gns3server/modules/virtualbox/__init__.py @@ -23,13 +23,12 @@ import sys import os import socket import shutil +import subprocess -from pkg_resources import parse_version from gns3server.modules import IModule from gns3server.config import Config from .virtualbox_vm import VirtualBoxVM from .virtualbox_error import VirtualBoxError -from .vboxwrapper_client import VboxWrapperClient from .nios.nio_udp import NIO_UDP from ..attic import find_unused_port @@ -61,26 +60,29 @@ class VirtualBox(IModule): def __init__(self, name, *args, **kwargs): - # get the vboxwrapper location (only non-Windows platforms) - if not sys.platform.startswith("win"): + # get the vboxmanage location + self._vboxmanage_path = None + if sys.platform.startswith("win") and "VBOX_INSTALL_PATH" in os.environ: + self._vboxmanage_path = os.path.join(os.environ["VBOX_INSTALL_PATH"], "VBoxManage.exe") + else: config = Config.instance() vbox_config = config.get_section_config(name.upper()) - self._vboxwrapper_path = vbox_config.get("vboxwrapper_path") - if not self._vboxwrapper_path or not os.path.isfile(self._vboxwrapper_path): + self._vboxmanage_path = vbox_config.get("vboxmanage_path") + if not self._vboxmanage_path or not os.path.isfile(self._vboxmanage_path): paths = [os.getcwd()] + os.environ["PATH"].split(os.pathsep) - # look for vboxwrapper in the current working directory and $PATH + # look for vboxmanage in the current working directory and $PATH for path in paths: try: - if "vboxwrapper" in os.listdir(path) and os.access(os.path.join(path, "vboxwrapper"), os.X_OK): - self._vboxwrapper_path = os.path.join(path, "vboxwrapper") + if "vboxmanage" in os.listdir(path) and os.access(os.path.join(path, "vboxmanage"), os.X_OK): + self._vboxmanage_path = os.path.join(path, "vboxmanage") break except OSError: continue - if not self._vboxwrapper_path: - log.warning("vboxwrapper couldn't be found!") - elif not os.access(self._vboxwrapper_path, os.X_OK): - log.warning("vboxwrapper is not executable") + if not self._vboxmanage_path: + log.warning("vboxmanage couldn't be found!") + elif not os.access(self._vboxmanage_path, os.X_OK): + log.warning("vboxmanage is not executable") # a new process start when calling IModule IModule.__init__(self, name, *args, **kwargs) @@ -97,59 +99,6 @@ class VirtualBox(IModule): self._projects_dir = kwargs["projects_dir"] self._tempdir = kwargs["temp_dir"] self._working_dir = self._projects_dir - self._vboxmanager = None - self._vboxwrapper = None - - def _start_vbox_service(self): - """ - Starts the VirtualBox backend. - vboxapi on Windows or vboxwrapper on other platforms. - """ - - if sys.platform.startswith("win"): - import pywintypes - import win32com.client - - try: - if win32com.client.gencache.is_readonly is True: - # dynamically generate the cache - # http://www.py2exe.org/index.cgi/IncludingTypelibs - # http://www.py2exe.org/index.cgi/UsingEnsureDispatch - win32com.client.gencache.is_readonly = False - #win32com.client.gencache.Rebuild() - win32com.client.gencache.GetGeneratePath() - - win32com.client.gencache.EnsureDispatch("VirtualBox.VirtualBox") - except pywintypes.com_error: - raise VirtualBoxError("VirtualBox is not installed.") - - try: - from .vboxapi_py3 import VirtualBoxManager - self._vboxmanager = VirtualBoxManager(None, None) - vbox_major_version, vbox_minor_version, _ = self._vboxmanager.vbox.version.split('.') - if parse_version("{}.{}".format(vbox_major_version, vbox_minor_version)) <= parse_version("4.1"): - raise VirtualBoxError("VirtualBox version must be >= 4.2") - except Exception as e: - self._vboxmanager = None - raise VirtualBoxError("Could not initialize the VirtualBox Manager: {}".format(e)) - - log.info("VirtualBox Manager has successful started: version is {} r{}".format(self._vboxmanager.vbox.version, - self._vboxmanager.vbox.revision)) - else: - - if not self._vboxwrapper_path: - raise VirtualBoxError("No vboxwrapper path has been configured") - - if not os.path.isfile(self._vboxwrapper_path): - raise VirtualBoxError("vboxwrapper path doesn't exist {}".format(self._vboxwrapper_path)) - - self._vboxwrapper = VboxWrapperClient(self._vboxwrapper_path, self._tempdir, "127.0.0.1") - #self._vboxwrapper.connect() - try: - self._vboxwrapper.start() - except VirtualBoxError: - self._vboxwrapper = None - raise def stop(self, signum=None): """ @@ -163,9 +112,6 @@ class VirtualBox(IModule): vbox_instance = self._vbox_instances[vbox_id] vbox_instance.delete() - if self._vboxwrapper and self._vboxwrapper.started: - self._vboxwrapper.stop() - IModule.stop(self, signum) # this will stop the I/O loop def get_vbox_instance(self, vbox_id): @@ -202,9 +148,6 @@ class VirtualBox(IModule): self._vbox_instances.clear() self._allocated_udp_ports.clear() - if self._vboxwrapper and self._vboxwrapper.connected(): - self._vboxwrapper.send("vboxwrapper reset") - log.info("VirtualBox module has been reset") @IModule.route("virtualbox.settings") @@ -214,7 +157,7 @@ class VirtualBox(IModule): Optional request parameters: - working_dir (path to a working directory) - - vboxwrapper_path (path to vboxwrapper) + - vboxmanage_path (path to vboxmanage) - project_name - console_start_port_range - console_end_port_range @@ -251,8 +194,8 @@ class VirtualBox(IModule): vbox_instance = self._vbox_instances[vbox_id] vbox_instance.working_dir = os.path.join(self._working_dir, "vbox", "vm-{}".format(vbox_instance.id)) - if "vboxwrapper_path" in request: - self._vboxwrapper_path = request["vboxwrapper_path"] + if "vboxmanage_path" in request: + self._vboxmanage_path = request["vboxmanage_path"] if "console_start_port_range" in request and "console_end_port_range" in request: self._console_start_port_range = request["console_start_port_range"] @@ -295,11 +238,10 @@ class VirtualBox(IModule): try: - if not self._vboxwrapper and not self._vboxmanager: - self._start_vbox_service() + if not self._vboxmanage_path or not os.path.exists(self._vboxmanage_path): + raise VirtualBoxError("Could not find VBoxManage, is VirtualBox correctly installed?") - vbox_instance = VirtualBoxVM(self._vboxwrapper, - self._vboxmanager, + vbox_instance = VirtualBoxVM(self._vboxmanage_path, name, vmname, self._working_dir, @@ -418,10 +360,7 @@ class VirtualBox(IModule): try: vbox_instance.start() except VirtualBoxError as e: - if self._vboxwrapper: - self.send_custom_error("{}: {}".format(e, self._vboxwrapper.read_stderr())) - else: - self.send_custom_error(str(e)) + self.send_custom_error(str(e)) return self.send_response(True) @@ -769,26 +708,36 @@ class VirtualBox(IModule): - List of VM names """ - if not self._vboxwrapper and not self._vboxmanager: + try: + + if request and "vboxmanage_path" in request: + vboxmanage_path = request["vboxmanage_path"] + else: + vboxmanage_path = self._vboxmanage_path + + if not vboxmanage_path or not os.path.exists(vboxmanage_path): + raise VirtualBoxError("Could not find VBoxManage, is VirtualBox correctly installed?") + + command = [self._vboxmanage_path, "--nologo", "list", "vms"] try: - self._start_vbox_service() - except VirtualBoxError as e: - self.send_custom_error(str(e)) - return - - if self._vboxwrapper: - vms = self._vboxwrapper.get_vm_list() - elif self._vboxmanager: - vms = [] - machines = self._vboxmanager.getArray(self._vboxmanager.vbox, "machines") - for machine in range(len(machines)): - vms.append(machines[machine].name) - else: - self.send_custom_error("Vboxmanager hasn't been initialized!") + result = subprocess.check_output(command, stderr=subprocess.STDOUT, universal_newlines=True, timeout=30) + except subprocess.CalledProcessError as e: + raise VirtualBoxError("Could not execute VBoxManage {}".format(e)) + except subprocess.TimeoutExpired: + raise VirtualBoxError("VBoxManage has timed out") + except VirtualBoxError as e: + self.send_custom_error(str(e)) return + vms = [] + lines = result.splitlines() + for line in lines: + vmname, uuid = line.rsplit(' ', 1) + vms.append(vmname.strip('"')) + response = {"server": self._host, "vms": vms} + self.send_response(response) @IModule.route("virtualbox.echo") diff --git a/gns3server/modules/virtualbox/vboxapi_py3/VirtualBox_constants.py b/gns3server/modules/virtualbox/vboxapi_py3/VirtualBox_constants.py deleted file mode 100644 index 87fc2748..00000000 --- a/gns3server/modules/virtualbox/vboxapi_py3/VirtualBox_constants.py +++ /dev/null @@ -1,1276 +0,0 @@ -# Copyright (C) Oracle Corporation -# -# This file is part of VirtualBox Open Source Edition (OSE), as -# available from http://www.virtualbox.org. This file is free software; -# you can redistribute it and/or modify it under the terms of the GNU -# General Public License (GPL) as published by the Free Software -# Foundation, in version 2 as it comes in the "COPYING" file of the -# VirtualBox OSE distribution. VirtualBox OSE is distributed in the -# hope that it will be useful, but WITHOUT ANY WARRANTY of any kind. -# -# This file is autogenerated from VirtualBox.xidl, DO NOT EDIT! -# - -class VirtualBoxReflectionInfo: - def __init__(self, isSym): - self.isSym = isSym - - _Values = { - 'SettingsVersion':{ - 'Null':0,'v1_0':1,'v1_1':2,'v1_2':3,'v1_3pre':4,'v1_3':5,'v1_4':6,'v1_5':7,'v1_6':8,'v1_7':9,'v1_8':10,'v1_9':11,'v1_10':12,'v1_11':13,'v1_12':14,'v1_13':15,'Future':99999}, - 'AccessMode':{ - 'ReadOnly':1,'ReadWrite':2}, - 'MachineState':{ - 'Null':0,'PoweredOff':1,'Saved':2,'Teleported':3,'Aborted':4,'Running':5,'Paused':6,'Stuck':7,'Teleporting':8,'LiveSnapshotting':9,'Starting':10,'Stopping':11,'Saving':12,'Restoring':13,'TeleportingPausedVM':14,'TeleportingIn':15,'FaultTolerantSyncing':16,'DeletingSnapshotOnline':17,'DeletingSnapshotPaused':18,'RestoringSnapshot':19,'DeletingSnapshot':20,'SettingUp':21,'FirstOnline':5,'LastOnline':18,'FirstTransient':8,'LastTransient':21}, - 'SessionState':{ - 'Null':0,'Unlocked':1,'Locked':2,'Spawning':3,'Unlocking':4}, - 'CPUPropertyType':{ - 'Null':0,'PAE':1,'Synthetic':2}, - 'HWVirtExPropertyType':{ - 'Null':0,'Enabled':1,'Exclusive':2,'VPID':3,'NestedPaging':4,'LargePages':5,'Force':6}, - 'FaultToleranceState':{ - 'Inactive':1,'Master':2,'Standby':3}, - 'LockType':{ - 'Write':2,'Shared':1,'VM':3}, - 'SessionType':{ - 'Null':0,'WriteLock':1,'Remote':2,'Shared':3}, - 'DeviceType':{ - 'Null':0,'Floppy':1,'DVD':2,'HardDisk':3,'Network':4,'USB':5,'SharedFolder':6}, - 'DeviceActivity':{ - 'Null':0,'Idle':1,'Reading':2,'Writing':3}, - 'ClipboardMode':{ - 'Disabled':0,'HostToGuest':1,'GuestToHost':2,'Bidirectional':3}, - 'DragAndDropMode':{ - 'Disabled':0,'HostToGuest':1,'GuestToHost':2,'Bidirectional':3}, - 'Scope':{ - 'Global':0,'Machine':1,'Session':2}, - 'BIOSBootMenuMode':{ - 'Disabled':0,'MenuOnly':1,'MessageAndMenu':2}, - 'ProcessorFeature':{ - 'HWVirtEx':0,'PAE':1,'LongMode':2,'NestedPaging':3}, - 'FirmwareType':{ - 'BIOS':1,'EFI':2,'EFI32':3,'EFI64':4,'EFIDUAL':5}, - 'PointingHIDType':{ - 'None':1,'PS2Mouse':2,'USBMouse':3,'USBTablet':4,'ComboMouse':5}, - 'KeyboardHIDType':{ - 'None':1,'PS2Keyboard':2,'USBKeyboard':3,'ComboKeyboard':4}, - 'VFSType':{ - 'File':1,'Cloud':2,'S3':3,'WebDav':4}, - 'VFSFileType':{ - 'Unknown':1,'Fifo':2,'DevChar':3,'Directory':4,'DevBlock':5,'File':6,'SymLink':7,'Socket':8,'WhiteOut':9}, - 'ImportOptions':{ - 'KeepAllMACs':1,'KeepNATMACs':2}, - 'VirtualSystemDescriptionType':{ - 'Ignore':1,'OS':2,'Name':3,'Product':4,'Vendor':5,'Version':6,'ProductUrl':7,'VendorUrl':8,'Description':9,'License':10,'Miscellaneous':11,'CPU':12,'Memory':13,'HardDiskControllerIDE':14,'HardDiskControllerSATA':15,'HardDiskControllerSCSI':16,'HardDiskControllerSAS':17,'HardDiskImage':18,'Floppy':19,'CDROM':20,'NetworkAdapter':21,'USBController':22,'SoundCard':23,'SettingsFile':24}, - 'VirtualSystemDescriptionValueType':{ - 'Reference':1,'Original':2,'Auto':3,'ExtraConfig':4}, - 'CleanupMode':{ - 'UnregisterOnly':1,'DetachAllReturnNone':2,'DetachAllReturnHardDisksOnly':3,'Full':4}, - 'CloneMode':{ - 'MachineState':1,'MachineAndChildStates':2,'AllStates':3}, - 'CloneOptions':{ - 'Link':1,'KeepAllMACs':2,'KeepNATMACs':3,'KeepDiskNames':4}, - 'AutostopType':{ - 'Disabled':1,'SaveState':2,'PowerOff':3,'AcpiShutdown':4}, - 'HostNetworkInterfaceMediumType':{ - 'Unknown':0,'Ethernet':1,'PPP':2,'SLIP':3}, - 'HostNetworkInterfaceStatus':{ - 'Unknown':0,'Up':1,'Down':2}, - 'HostNetworkInterfaceType':{ - 'Bridged':1,'HostOnly':2}, - 'AdditionsFacilityType':{ - 'None':0,'VBoxGuestDriver':20,'AutoLogon':90,'VBoxService':100,'VBoxTrayClient':101,'Seamless':1000,'Graphics':1100,'All':2147483646}, - 'AdditionsFacilityClass':{ - 'None':0,'Driver':10,'Service':30,'Program':50,'Feature':100,'ThirdParty':999,'All':2147483646}, - 'AdditionsFacilityStatus':{ - 'Inactive':0,'Paused':1,'PreInit':20,'Init':30,'Active':50,'Terminating':100,'Terminated':101,'Failed':800,'Unknown':999}, - 'AdditionsRunLevelType':{ - 'None':0,'System':1,'Userland':2,'Desktop':3}, - 'AdditionsUpdateFlag':{ - 'None':0,'WaitForUpdateStartOnly':1}, - 'FileSeekType':{ - 'Set':0,'Current':1}, - 'ProcessInputFlag':{ - 'None':0,'EndOfFile':1}, - 'ProcessOutputFlag':{ - 'None':0,'StdErr':1}, - 'ProcessWaitForFlag':{ - 'None':0,'Start':1,'Terminate':2,'StdIn':4,'StdOut':8,'StdErr':16}, - 'ProcessWaitResult':{ - 'None':0,'Start':1,'Terminate':2,'Status':3,'Error':4,'Timeout':5,'StdIn':6,'StdOut':7,'StdErr':8,'WaitFlagNotSupported':9}, - 'CopyFileFlag':{ - 'None':0,'Recursive':1,'Update':2,'FollowLinks':4}, - 'DirectoryCreateFlag':{ - 'None':0,'Parents':1}, - 'DirectoryRemoveRecFlag':{ - 'None':0,'ContentAndDir':1,'ContentOnly':2}, - 'PathRenameFlag':{ - 'None':0,'NoReplace':1,'Replace':2,'NoSymlinks':4}, - 'ProcessCreateFlag':{ - 'None':0,'WaitForProcessStartOnly':1,'IgnoreOrphanedProcesses':2,'Hidden':4,'NoProfile':8,'WaitForStdOut':16,'WaitForStdErr':32,'ExpandArguments':64}, - 'ProcessPriority':{ - 'Invalid':0,'Default':1}, - 'SymlinkType':{ - 'Unknown':0,'Directory':1,'File':2}, - 'SymlinkReadFlag':{ - 'None':0,'NoSymlinks':1}, - 'ProcessStatus':{ - 'Undefined':0,'Starting':10,'Started':100,'Paused':110,'Terminating':480,'TerminatedNormally':500,'TerminatedSignal':510,'TerminatedAbnormally':511,'TimedOutKilled':512,'TimedOutAbnormally':513,'Down':600,'Error':800}, - 'FsObjType':{ - 'Undefined':0,'FIFO':1,'DevChar':10,'DevBlock':11,'Directory':50,'File':80,'Symlink':100,'Socket':200,'Whiteout':400}, - 'DragAndDropAction':{ - 'Ignore':0,'Copy':1,'Move':2,'Link':3}, - 'DirectoryOpenFlag':{ - 'None':0,'NoSymlinks':1}, - 'MediumState':{ - 'NotCreated':0,'Created':1,'LockedRead':2,'LockedWrite':3,'Inaccessible':4,'Creating':5,'Deleting':6}, - 'MediumType':{ - 'Normal':0,'Immutable':1,'Writethrough':2,'Shareable':3,'Readonly':4,'MultiAttach':5}, - 'MediumVariant':{ - 'Standard':0,'VmdkSplit2G':0x01,'VmdkRawDisk':0x02,'VmdkStreamOptimized':0x04,'VmdkESX':0x08,'Fixed':0x10000,'Diff':0x20000,'NoCreateDir':0x40000000}, - 'DataType':{ - 'Int32':0,'Int8':1,'String':2}, - 'DataFlags':{ - 'None':0x00,'Mandatory':0x01,'Expert':0x02,'Array':0x04,'FlagMask':0x07}, - 'MediumFormatCapabilities':{ - 'Uuid':0x01,'CreateFixed':0x02,'CreateDynamic':0x04,'CreateSplit2G':0x08,'Differencing':0x10,'Asynchronous':0x20,'File':0x40,'Properties':0x80,'TcpNetworking':0x100,'VFS':0x200,'CapabilityMask':0x3FF}, - 'MouseButtonState':{ - 'LeftButton':0x01,'RightButton':0x02,'MiddleButton':0x04,'WheelUp':0x08,'WheelDown':0x10,'XButton1':0x20,'XButton2':0x40,'MouseStateMask':0x7F}, - 'FramebufferPixelFormat':{ - 'Opaque':0,'FOURCC_RGB':0x32424752}, - 'NetworkAttachmentType':{ - 'Null':0,'NAT':1,'Bridged':2,'Internal':3,'HostOnly':4,'Generic':5}, - 'NetworkAdapterType':{ - 'Null':0,'Am79C970A':1,'Am79C973':2,'I82540EM':3,'I82543GC':4,'I82545EM':5,'Virtio':6}, - 'NetworkAdapterPromiscModePolicy':{ - 'Deny':1,'AllowNetwork':2,'AllowAll':3}, - 'PortMode':{ - 'Disconnected':0,'HostPipe':1,'HostDevice':2,'RawFile':3}, - 'USBDeviceState':{ - 'NotSupported':0,'Unavailable':1,'Busy':2,'Available':3,'Held':4,'Captured':5}, - 'USBDeviceFilterAction':{ - 'Null':0,'Ignore':1,'Hold':2}, - 'AudioDriverType':{ - 'Null':0,'WinMM':1,'OSS':2,'ALSA':3,'DirectSound':4,'CoreAudio':5,'MMPM':6,'Pulse':7,'SolAudio':8}, - 'AudioControllerType':{ - 'AC97':0,'SB16':1,'HDA':2}, - 'AuthType':{ - 'Null':0,'External':1,'Guest':2}, - 'StorageBus':{ - 'Null':0,'IDE':1,'SATA':2,'SCSI':3,'Floppy':4,'SAS':5}, - 'StorageControllerType':{ - 'Null':0,'LsiLogic':1,'BusLogic':2,'IntelAhci':3,'PIIX3':4,'PIIX4':5,'ICH6':6,'I82078':7,'LsiLogicSas':8}, - 'ChipsetType':{ - 'Null':0,'PIIX3':1,'ICH9':2}, - 'NATAliasMode':{ - 'AliasLog':0x1,'AliasProxyOnly':0x02,'AliasUseSamePorts':0x04}, - 'NATProtocol':{ - 'UDP':0,'TCP':1}, - 'BandwidthGroupType':{ - 'Null':0,'Disk':1,'Network':2}, - 'VBoxEventType':{ - 'Invalid':0,'Any':1,'Vetoable':2,'MachineEvent':3,'SnapshotEvent':4,'InputEvent':5,'LastWildcard':31,'OnMachineStateChanged':32,'OnMachineDataChanged':33,'OnExtraDataChanged':34,'OnExtraDataCanChange':35,'OnMediumRegistered':36,'OnMachineRegistered':37,'OnSessionStateChanged':38,'OnSnapshotTaken':39,'OnSnapshotDeleted':40,'OnSnapshotChanged':41,'OnGuestPropertyChanged':42,'OnMousePointerShapeChanged':43,'OnMouseCapabilityChanged':44,'OnKeyboardLedsChanged':45,'OnStateChanged':46,'OnAdditionsStateChanged':47,'OnNetworkAdapterChanged':48,'OnSerialPortChanged':49,'OnParallelPortChanged':50,'OnStorageControllerChanged':51,'OnMediumChanged':52,'OnVRDEServerChanged':53,'OnUSBControllerChanged':54,'OnUSBDeviceStateChanged':55,'OnSharedFolderChanged':56,'OnRuntimeError':57,'OnCanShowWindow':58,'OnShowWindow':59,'OnCPUChanged':60,'OnVRDEServerInfoChanged':61,'OnEventSourceChanged':62,'OnCPUExecutionCapChanged':63,'OnGuestKeyboard':64,'OnGuestMouse':65,'OnNATRedirect':66,'OnHostPCIDevicePlug':67,'OnVBoxSVCAvailabilityChanged':68,'OnBandwidthGroupChanged':69,'OnGuestMonitorChanged':70,'OnStorageDeviceChanged':71,'OnClipboardModeChanged':72,'OnDragAndDropModeChanged':73,'Last':74}, - 'GuestMonitorChangedEventType':{ - 'Enabled':0,'Disabled':1,'NewOrigin':2}} - - _ValuesSym = { - 'SettingsVersion':{ - 'Null': 'Null','v1_0': 'v1_0','v1_1': 'v1_1','v1_2': 'v1_2','v1_3pre': 'v1_3pre','v1_3': 'v1_3','v1_4': 'v1_4','v1_5': 'v1_5','v1_6': 'v1_6','v1_7': 'v1_7','v1_8': 'v1_8','v1_9': 'v1_9','v1_10': 'v1_10','v1_11': 'v1_11','v1_12': 'v1_12','v1_13': 'v1_13','Future': 'Future'}, - 'AccessMode':{ - 'ReadOnly': 'ReadOnly','ReadWrite': 'ReadWrite'}, - 'MachineState':{ - 'Null': 'Null','PoweredOff': 'PoweredOff','Saved': 'Saved','Teleported': 'Teleported','Aborted': 'Aborted','Running': 'Running','Paused': 'Paused','Stuck': 'Stuck','Teleporting': 'Teleporting','LiveSnapshotting': 'LiveSnapshotting','Starting': 'Starting','Stopping': 'Stopping','Saving': 'Saving','Restoring': 'Restoring','TeleportingPausedVM': 'TeleportingPausedVM','TeleportingIn': 'TeleportingIn','FaultTolerantSyncing': 'FaultTolerantSyncing','DeletingSnapshotOnline': 'DeletingSnapshotOnline','DeletingSnapshotPaused': 'DeletingSnapshotPaused','RestoringSnapshot': 'RestoringSnapshot','DeletingSnapshot': 'DeletingSnapshot','SettingUp': 'SettingUp','FirstOnline': 'FirstOnline','LastOnline': 'LastOnline','FirstTransient': 'FirstTransient','LastTransient': 'LastTransient'}, - 'SessionState':{ - 'Null': 'Null','Unlocked': 'Unlocked','Locked': 'Locked','Spawning': 'Spawning','Unlocking': 'Unlocking'}, - 'CPUPropertyType':{ - 'Null': 'Null','PAE': 'PAE','Synthetic': 'Synthetic'}, - 'HWVirtExPropertyType':{ - 'Null': 'Null','Enabled': 'Enabled','Exclusive': 'Exclusive','VPID': 'VPID','NestedPaging': 'NestedPaging','LargePages': 'LargePages','Force': 'Force'}, - 'FaultToleranceState':{ - 'Inactive': 'Inactive','Master': 'Master','Standby': 'Standby'}, - 'LockType':{ - 'Write': 'Write','Shared': 'Shared','VM': 'VM'}, - 'SessionType':{ - 'Null': 'Null','WriteLock': 'WriteLock','Remote': 'Remote','Shared': 'Shared'}, - 'DeviceType':{ - 'Null': 'Null','Floppy': 'Floppy','DVD': 'DVD','HardDisk': 'HardDisk','Network': 'Network','USB': 'USB','SharedFolder': 'SharedFolder'}, - 'DeviceActivity':{ - 'Null': 'Null','Idle': 'Idle','Reading': 'Reading','Writing': 'Writing'}, - 'ClipboardMode':{ - 'Disabled': 'Disabled','HostToGuest': 'HostToGuest','GuestToHost': 'GuestToHost','Bidirectional': 'Bidirectional'}, - 'DragAndDropMode':{ - 'Disabled': 'Disabled','HostToGuest': 'HostToGuest','GuestToHost': 'GuestToHost','Bidirectional': 'Bidirectional'}, - 'Scope':{ - 'Global': 'Global','Machine': 'Machine','Session': 'Session'}, - 'BIOSBootMenuMode':{ - 'Disabled': 'Disabled','MenuOnly': 'MenuOnly','MessageAndMenu': 'MessageAndMenu'}, - 'ProcessorFeature':{ - 'HWVirtEx': 'HWVirtEx','PAE': 'PAE','LongMode': 'LongMode','NestedPaging': 'NestedPaging'}, - 'FirmwareType':{ - 'BIOS': 'BIOS','EFI': 'EFI','EFI32': 'EFI32','EFI64': 'EFI64','EFIDUAL': 'EFIDUAL'}, - 'PointingHIDType':{ - 'None': 'None','PS2Mouse': 'PS2Mouse','USBMouse': 'USBMouse','USBTablet': 'USBTablet','ComboMouse': 'ComboMouse'}, - 'KeyboardHIDType':{ - 'None': 'None','PS2Keyboard': 'PS2Keyboard','USBKeyboard': 'USBKeyboard','ComboKeyboard': 'ComboKeyboard'}, - 'VFSType':{ - 'File': 'File','Cloud': 'Cloud','S3': 'S3','WebDav': 'WebDav'}, - 'VFSFileType':{ - 'Unknown': 'Unknown','Fifo': 'Fifo','DevChar': 'DevChar','Directory': 'Directory','DevBlock': 'DevBlock','File': 'File','SymLink': 'SymLink','Socket': 'Socket','WhiteOut': 'WhiteOut'}, - 'ImportOptions':{ - 'KeepAllMACs': 'KeepAllMACs','KeepNATMACs': 'KeepNATMACs'}, - 'VirtualSystemDescriptionType':{ - 'Ignore': 'Ignore','OS': 'OS','Name': 'Name','Product': 'Product','Vendor': 'Vendor','Version': 'Version','ProductUrl': 'ProductUrl','VendorUrl': 'VendorUrl','Description': 'Description','License': 'License','Miscellaneous': 'Miscellaneous','CPU': 'CPU','Memory': 'Memory','HardDiskControllerIDE': 'HardDiskControllerIDE','HardDiskControllerSATA': 'HardDiskControllerSATA','HardDiskControllerSCSI': 'HardDiskControllerSCSI','HardDiskControllerSAS': 'HardDiskControllerSAS','HardDiskImage': 'HardDiskImage','Floppy': 'Floppy','CDROM': 'CDROM','NetworkAdapter': 'NetworkAdapter','USBController': 'USBController','SoundCard': 'SoundCard','SettingsFile': 'SettingsFile'}, - 'VirtualSystemDescriptionValueType':{ - 'Reference': 'Reference','Original': 'Original','Auto': 'Auto','ExtraConfig': 'ExtraConfig'}, - 'CleanupMode':{ - 'UnregisterOnly': 'UnregisterOnly','DetachAllReturnNone': 'DetachAllReturnNone','DetachAllReturnHardDisksOnly': 'DetachAllReturnHardDisksOnly','Full': 'Full'}, - 'CloneMode':{ - 'MachineState': 'MachineState','MachineAndChildStates': 'MachineAndChildStates','AllStates': 'AllStates'}, - 'CloneOptions':{ - 'Link': 'Link','KeepAllMACs': 'KeepAllMACs','KeepNATMACs': 'KeepNATMACs','KeepDiskNames': 'KeepDiskNames'}, - 'AutostopType':{ - 'Disabled': 'Disabled','SaveState': 'SaveState','PowerOff': 'PowerOff','AcpiShutdown': 'AcpiShutdown'}, - 'HostNetworkInterfaceMediumType':{ - 'Unknown': 'Unknown','Ethernet': 'Ethernet','PPP': 'PPP','SLIP': 'SLIP'}, - 'HostNetworkInterfaceStatus':{ - 'Unknown': 'Unknown','Up': 'Up','Down': 'Down'}, - 'HostNetworkInterfaceType':{ - 'Bridged': 'Bridged','HostOnly': 'HostOnly'}, - 'AdditionsFacilityType':{ - 'None': 'None','VBoxGuestDriver': 'VBoxGuestDriver','AutoLogon': 'AutoLogon','VBoxService': 'VBoxService','VBoxTrayClient': 'VBoxTrayClient','Seamless': 'Seamless','Graphics': 'Graphics','All': 'All'}, - 'AdditionsFacilityClass':{ - 'None': 'None','Driver': 'Driver','Service': 'Service','Program': 'Program','Feature': 'Feature','ThirdParty': 'ThirdParty','All': 'All'}, - 'AdditionsFacilityStatus':{ - 'Inactive': 'Inactive','Paused': 'Paused','PreInit': 'PreInit','Init': 'Init','Active': 'Active','Terminating': 'Terminating','Terminated': 'Terminated','Failed': 'Failed','Unknown': 'Unknown'}, - 'AdditionsRunLevelType':{ - 'None': 'None','System': 'System','Userland': 'Userland','Desktop': 'Desktop'}, - 'AdditionsUpdateFlag':{ - 'None': 'None','WaitForUpdateStartOnly': 'WaitForUpdateStartOnly'}, - 'FileSeekType':{ - 'Set': 'Set','Current': 'Current'}, - 'ProcessInputFlag':{ - 'None': 'None','EndOfFile': 'EndOfFile'}, - 'ProcessOutputFlag':{ - 'None': 'None','StdErr': 'StdErr'}, - 'ProcessWaitForFlag':{ - 'None': 'None','Start': 'Start','Terminate': 'Terminate','StdIn': 'StdIn','StdOut': 'StdOut','StdErr': 'StdErr'}, - 'ProcessWaitResult':{ - 'None': 'None','Start': 'Start','Terminate': 'Terminate','Status': 'Status','Error': 'Error','Timeout': 'Timeout','StdIn': 'StdIn','StdOut': 'StdOut','StdErr': 'StdErr','WaitFlagNotSupported': 'WaitFlagNotSupported'}, - 'CopyFileFlag':{ - 'None': 'None','Recursive': 'Recursive','Update': 'Update','FollowLinks': 'FollowLinks'}, - 'DirectoryCreateFlag':{ - 'None': 'None','Parents': 'Parents'}, - 'DirectoryRemoveRecFlag':{ - 'None': 'None','ContentAndDir': 'ContentAndDir','ContentOnly': 'ContentOnly'}, - 'PathRenameFlag':{ - 'None': 'None','NoReplace': 'NoReplace','Replace': 'Replace','NoSymlinks': 'NoSymlinks'}, - 'ProcessCreateFlag':{ - 'None': 'None','WaitForProcessStartOnly': 'WaitForProcessStartOnly','IgnoreOrphanedProcesses': 'IgnoreOrphanedProcesses','Hidden': 'Hidden','NoProfile': 'NoProfile','WaitForStdOut': 'WaitForStdOut','WaitForStdErr': 'WaitForStdErr','ExpandArguments': 'ExpandArguments'}, - 'ProcessPriority':{ - 'Invalid': 'Invalid','Default': 'Default'}, - 'SymlinkType':{ - 'Unknown': 'Unknown','Directory': 'Directory','File': 'File'}, - 'SymlinkReadFlag':{ - 'None': 'None','NoSymlinks': 'NoSymlinks'}, - 'ProcessStatus':{ - 'Undefined': 'Undefined','Starting': 'Starting','Started': 'Started','Paused': 'Paused','Terminating': 'Terminating','TerminatedNormally': 'TerminatedNormally','TerminatedSignal': 'TerminatedSignal','TerminatedAbnormally': 'TerminatedAbnormally','TimedOutKilled': 'TimedOutKilled','TimedOutAbnormally': 'TimedOutAbnormally','Down': 'Down','Error': 'Error'}, - 'FsObjType':{ - 'Undefined': 'Undefined','FIFO': 'FIFO','DevChar': 'DevChar','DevBlock': 'DevBlock','Directory': 'Directory','File': 'File','Symlink': 'Symlink','Socket': 'Socket','Whiteout': 'Whiteout'}, - 'DragAndDropAction':{ - 'Ignore': 'Ignore','Copy': 'Copy','Move': 'Move','Link': 'Link'}, - 'DirectoryOpenFlag':{ - 'None': 'None','NoSymlinks': 'NoSymlinks'}, - 'MediumState':{ - 'NotCreated': 'NotCreated','Created': 'Created','LockedRead': 'LockedRead','LockedWrite': 'LockedWrite','Inaccessible': 'Inaccessible','Creating': 'Creating','Deleting': 'Deleting'}, - 'MediumType':{ - 'Normal': 'Normal','Immutable': 'Immutable','Writethrough': 'Writethrough','Shareable': 'Shareable','Readonly': 'Readonly','MultiAttach': 'MultiAttach'}, - 'MediumVariant':{ - 'Standard': 'Standard','VmdkSplit2G': 'VmdkSplit2G','VmdkRawDisk': 'VmdkRawDisk','VmdkStreamOptimized': 'VmdkStreamOptimized','VmdkESX': 'VmdkESX','Fixed': 'Fixed','Diff': 'Diff','NoCreateDir': 'NoCreateDir'}, - 'DataType':{ - 'Int32': 'Int32','Int8': 'Int8','String': 'String'}, - 'DataFlags':{ - 'None': 'None','Mandatory': 'Mandatory','Expert': 'Expert','Array': 'Array','FlagMask': 'FlagMask'}, - 'MediumFormatCapabilities':{ - 'Uuid': 'Uuid','CreateFixed': 'CreateFixed','CreateDynamic': 'CreateDynamic','CreateSplit2G': 'CreateSplit2G','Differencing': 'Differencing','Asynchronous': 'Asynchronous','File': 'File','Properties': 'Properties','TcpNetworking': 'TcpNetworking','VFS': 'VFS','CapabilityMask': 'CapabilityMask'}, - 'MouseButtonState':{ - 'LeftButton': 'LeftButton','RightButton': 'RightButton','MiddleButton': 'MiddleButton','WheelUp': 'WheelUp','WheelDown': 'WheelDown','XButton1': 'XButton1','XButton2': 'XButton2','MouseStateMask': 'MouseStateMask'}, - 'FramebufferPixelFormat':{ - 'Opaque': 'Opaque','FOURCC_RGB': 'FOURCC_RGB'}, - 'NetworkAttachmentType':{ - 'Null': 'Null','NAT': 'NAT','Bridged': 'Bridged','Internal': 'Internal','HostOnly': 'HostOnly','Generic': 'Generic'}, - 'NetworkAdapterType':{ - 'Null': 'Null','Am79C970A': 'Am79C970A','Am79C973': 'Am79C973','I82540EM': 'I82540EM','I82543GC': 'I82543GC','I82545EM': 'I82545EM','Virtio': 'Virtio'}, - 'NetworkAdapterPromiscModePolicy':{ - 'Deny': 'Deny','AllowNetwork': 'AllowNetwork','AllowAll': 'AllowAll'}, - 'PortMode':{ - 'Disconnected': 'Disconnected','HostPipe': 'HostPipe','HostDevice': 'HostDevice','RawFile': 'RawFile'}, - 'USBDeviceState':{ - 'NotSupported': 'NotSupported','Unavailable': 'Unavailable','Busy': 'Busy','Available': 'Available','Held': 'Held','Captured': 'Captured'}, - 'USBDeviceFilterAction':{ - 'Null': 'Null','Ignore': 'Ignore','Hold': 'Hold'}, - 'AudioDriverType':{ - 'Null': 'Null','WinMM': 'WinMM','OSS': 'OSS','ALSA': 'ALSA','DirectSound': 'DirectSound','CoreAudio': 'CoreAudio','MMPM': 'MMPM','Pulse': 'Pulse','SolAudio': 'SolAudio'}, - 'AudioControllerType':{ - 'AC97': 'AC97','SB16': 'SB16','HDA': 'HDA'}, - 'AuthType':{ - 'Null': 'Null','External': 'External','Guest': 'Guest'}, - 'StorageBus':{ - 'Null': 'Null','IDE': 'IDE','SATA': 'SATA','SCSI': 'SCSI','Floppy': 'Floppy','SAS': 'SAS'}, - 'StorageControllerType':{ - 'Null': 'Null','LsiLogic': 'LsiLogic','BusLogic': 'BusLogic','IntelAhci': 'IntelAhci','PIIX3': 'PIIX3','PIIX4': 'PIIX4','ICH6': 'ICH6','I82078': 'I82078','LsiLogicSas': 'LsiLogicSas'}, - 'ChipsetType':{ - 'Null': 'Null','PIIX3': 'PIIX3','ICH9': 'ICH9'}, - 'NATAliasMode':{ - 'AliasLog': 'AliasLog','AliasProxyOnly': 'AliasProxyOnly','AliasUseSamePorts': 'AliasUseSamePorts'}, - 'NATProtocol':{ - 'UDP': 'UDP','TCP': 'TCP'}, - 'BandwidthGroupType':{ - 'Null': 'Null','Disk': 'Disk','Network': 'Network'}, - 'VBoxEventType':{ - 'Invalid': 'Invalid','Any': 'Any','Vetoable': 'Vetoable','MachineEvent': 'MachineEvent','SnapshotEvent': 'SnapshotEvent','InputEvent': 'InputEvent','LastWildcard': 'LastWildcard','OnMachineStateChanged': 'OnMachineStateChanged','OnMachineDataChanged': 'OnMachineDataChanged','OnExtraDataChanged': 'OnExtraDataChanged','OnExtraDataCanChange': 'OnExtraDataCanChange','OnMediumRegistered': 'OnMediumRegistered','OnMachineRegistered': 'OnMachineRegistered','OnSessionStateChanged': 'OnSessionStateChanged','OnSnapshotTaken': 'OnSnapshotTaken','OnSnapshotDeleted': 'OnSnapshotDeleted','OnSnapshotChanged': 'OnSnapshotChanged','OnGuestPropertyChanged': 'OnGuestPropertyChanged','OnMousePointerShapeChanged': 'OnMousePointerShapeChanged','OnMouseCapabilityChanged': 'OnMouseCapabilityChanged','OnKeyboardLedsChanged': 'OnKeyboardLedsChanged','OnStateChanged': 'OnStateChanged','OnAdditionsStateChanged': 'OnAdditionsStateChanged','OnNetworkAdapterChanged': 'OnNetworkAdapterChanged','OnSerialPortChanged': 'OnSerialPortChanged','OnParallelPortChanged': 'OnParallelPortChanged','OnStorageControllerChanged': 'OnStorageControllerChanged','OnMediumChanged': 'OnMediumChanged','OnVRDEServerChanged': 'OnVRDEServerChanged','OnUSBControllerChanged': 'OnUSBControllerChanged','OnUSBDeviceStateChanged': 'OnUSBDeviceStateChanged','OnSharedFolderChanged': 'OnSharedFolderChanged','OnRuntimeError': 'OnRuntimeError','OnCanShowWindow': 'OnCanShowWindow','OnShowWindow': 'OnShowWindow','OnCPUChanged': 'OnCPUChanged','OnVRDEServerInfoChanged': 'OnVRDEServerInfoChanged','OnEventSourceChanged': 'OnEventSourceChanged','OnCPUExecutionCapChanged': 'OnCPUExecutionCapChanged','OnGuestKeyboard': 'OnGuestKeyboard','OnGuestMouse': 'OnGuestMouse','OnNATRedirect': 'OnNATRedirect','OnHostPCIDevicePlug': 'OnHostPCIDevicePlug','OnVBoxSVCAvailabilityChanged': 'OnVBoxSVCAvailabilityChanged','OnBandwidthGroupChanged': 'OnBandwidthGroupChanged','OnGuestMonitorChanged': 'OnGuestMonitorChanged','OnStorageDeviceChanged': 'OnStorageDeviceChanged','OnClipboardModeChanged': 'OnClipboardModeChanged','OnDragAndDropModeChanged': 'OnDragAndDropModeChanged','Last': 'Last'}, - 'GuestMonitorChangedEventType':{ - 'Enabled': 'Enabled','Disabled': 'Disabled','NewOrigin': 'NewOrigin'}} - - _ValuesFlat = { - 'SettingsVersion_Null':0, - 'SettingsVersion_v1_0':1, - 'SettingsVersion_v1_1':2, - 'SettingsVersion_v1_2':3, - 'SettingsVersion_v1_3pre':4, - 'SettingsVersion_v1_3':5, - 'SettingsVersion_v1_4':6, - 'SettingsVersion_v1_5':7, - 'SettingsVersion_v1_6':8, - 'SettingsVersion_v1_7':9, - 'SettingsVersion_v1_8':10, - 'SettingsVersion_v1_9':11, - 'SettingsVersion_v1_10':12, - 'SettingsVersion_v1_11':13, - 'SettingsVersion_v1_12':14, - 'SettingsVersion_v1_13':15, - 'SettingsVersion_Future':99999, - 'AccessMode_ReadOnly':1, - 'AccessMode_ReadWrite':2, - 'MachineState_Null':0, - 'MachineState_PoweredOff':1, - 'MachineState_Saved':2, - 'MachineState_Teleported':3, - 'MachineState_Aborted':4, - 'MachineState_Running':5, - 'MachineState_Paused':6, - 'MachineState_Stuck':7, - 'MachineState_Teleporting':8, - 'MachineState_LiveSnapshotting':9, - 'MachineState_Starting':10, - 'MachineState_Stopping':11, - 'MachineState_Saving':12, - 'MachineState_Restoring':13, - 'MachineState_TeleportingPausedVM':14, - 'MachineState_TeleportingIn':15, - 'MachineState_FaultTolerantSyncing':16, - 'MachineState_DeletingSnapshotOnline':17, - 'MachineState_DeletingSnapshotPaused':18, - 'MachineState_RestoringSnapshot':19, - 'MachineState_DeletingSnapshot':20, - 'MachineState_SettingUp':21, - 'MachineState_FirstOnline':5, - 'MachineState_LastOnline':18, - 'MachineState_FirstTransient':8, - 'MachineState_LastTransient':21, - 'SessionState_Null':0, - 'SessionState_Unlocked':1, - 'SessionState_Locked':2, - 'SessionState_Spawning':3, - 'SessionState_Unlocking':4, - 'CPUPropertyType_Null':0, - 'CPUPropertyType_PAE':1, - 'CPUPropertyType_Synthetic':2, - 'HWVirtExPropertyType_Null':0, - 'HWVirtExPropertyType_Enabled':1, - 'HWVirtExPropertyType_Exclusive':2, - 'HWVirtExPropertyType_VPID':3, - 'HWVirtExPropertyType_NestedPaging':4, - 'HWVirtExPropertyType_LargePages':5, - 'HWVirtExPropertyType_Force':6, - 'FaultToleranceState_Inactive':1, - 'FaultToleranceState_Master':2, - 'FaultToleranceState_Standby':3, - 'LockType_Write':2, - 'LockType_Shared':1, - 'LockType_VM':3, - 'SessionType_Null':0, - 'SessionType_WriteLock':1, - 'SessionType_Remote':2, - 'SessionType_Shared':3, - 'DeviceType_Null':0, - 'DeviceType_Floppy':1, - 'DeviceType_DVD':2, - 'DeviceType_HardDisk':3, - 'DeviceType_Network':4, - 'DeviceType_USB':5, - 'DeviceType_SharedFolder':6, - 'DeviceActivity_Null':0, - 'DeviceActivity_Idle':1, - 'DeviceActivity_Reading':2, - 'DeviceActivity_Writing':3, - 'ClipboardMode_Disabled':0, - 'ClipboardMode_HostToGuest':1, - 'ClipboardMode_GuestToHost':2, - 'ClipboardMode_Bidirectional':3, - 'DragAndDropMode_Disabled':0, - 'DragAndDropMode_HostToGuest':1, - 'DragAndDropMode_GuestToHost':2, - 'DragAndDropMode_Bidirectional':3, - 'Scope_Global':0, - 'Scope_Machine':1, - 'Scope_Session':2, - 'BIOSBootMenuMode_Disabled':0, - 'BIOSBootMenuMode_MenuOnly':1, - 'BIOSBootMenuMode_MessageAndMenu':2, - 'ProcessorFeature_HWVirtEx':0, - 'ProcessorFeature_PAE':1, - 'ProcessorFeature_LongMode':2, - 'ProcessorFeature_NestedPaging':3, - 'FirmwareType_BIOS':1, - 'FirmwareType_EFI':2, - 'FirmwareType_EFI32':3, - 'FirmwareType_EFI64':4, - 'FirmwareType_EFIDUAL':5, - 'PointingHIDType_None':1, - 'PointingHIDType_PS2Mouse':2, - 'PointingHIDType_USBMouse':3, - 'PointingHIDType_USBTablet':4, - 'PointingHIDType_ComboMouse':5, - 'KeyboardHIDType_None':1, - 'KeyboardHIDType_PS2Keyboard':2, - 'KeyboardHIDType_USBKeyboard':3, - 'KeyboardHIDType_ComboKeyboard':4, - 'VFSType_File':1, - 'VFSType_Cloud':2, - 'VFSType_S3':3, - 'VFSType_WebDav':4, - 'VFSFileType_Unknown':1, - 'VFSFileType_Fifo':2, - 'VFSFileType_DevChar':3, - 'VFSFileType_Directory':4, - 'VFSFileType_DevBlock':5, - 'VFSFileType_File':6, - 'VFSFileType_SymLink':7, - 'VFSFileType_Socket':8, - 'VFSFileType_WhiteOut':9, - 'ImportOptions_KeepAllMACs':1, - 'ImportOptions_KeepNATMACs':2, - 'VirtualSystemDescriptionType_Ignore':1, - 'VirtualSystemDescriptionType_OS':2, - 'VirtualSystemDescriptionType_Name':3, - 'VirtualSystemDescriptionType_Product':4, - 'VirtualSystemDescriptionType_Vendor':5, - 'VirtualSystemDescriptionType_Version':6, - 'VirtualSystemDescriptionType_ProductUrl':7, - 'VirtualSystemDescriptionType_VendorUrl':8, - 'VirtualSystemDescriptionType_Description':9, - 'VirtualSystemDescriptionType_License':10, - 'VirtualSystemDescriptionType_Miscellaneous':11, - 'VirtualSystemDescriptionType_CPU':12, - 'VirtualSystemDescriptionType_Memory':13, - 'VirtualSystemDescriptionType_HardDiskControllerIDE':14, - 'VirtualSystemDescriptionType_HardDiskControllerSATA':15, - 'VirtualSystemDescriptionType_HardDiskControllerSCSI':16, - 'VirtualSystemDescriptionType_HardDiskControllerSAS':17, - 'VirtualSystemDescriptionType_HardDiskImage':18, - 'VirtualSystemDescriptionType_Floppy':19, - 'VirtualSystemDescriptionType_CDROM':20, - 'VirtualSystemDescriptionType_NetworkAdapter':21, - 'VirtualSystemDescriptionType_USBController':22, - 'VirtualSystemDescriptionType_SoundCard':23, - 'VirtualSystemDescriptionType_SettingsFile':24, - 'VirtualSystemDescriptionValueType_Reference':1, - 'VirtualSystemDescriptionValueType_Original':2, - 'VirtualSystemDescriptionValueType_Auto':3, - 'VirtualSystemDescriptionValueType_ExtraConfig':4, - 'CleanupMode_UnregisterOnly':1, - 'CleanupMode_DetachAllReturnNone':2, - 'CleanupMode_DetachAllReturnHardDisksOnly':3, - 'CleanupMode_Full':4, - 'CloneMode_MachineState':1, - 'CloneMode_MachineAndChildStates':2, - 'CloneMode_AllStates':3, - 'CloneOptions_Link':1, - 'CloneOptions_KeepAllMACs':2, - 'CloneOptions_KeepNATMACs':3, - 'CloneOptions_KeepDiskNames':4, - 'AutostopType_Disabled':1, - 'AutostopType_SaveState':2, - 'AutostopType_PowerOff':3, - 'AutostopType_AcpiShutdown':4, - 'HostNetworkInterfaceMediumType_Unknown':0, - 'HostNetworkInterfaceMediumType_Ethernet':1, - 'HostNetworkInterfaceMediumType_PPP':2, - 'HostNetworkInterfaceMediumType_SLIP':3, - 'HostNetworkInterfaceStatus_Unknown':0, - 'HostNetworkInterfaceStatus_Up':1, - 'HostNetworkInterfaceStatus_Down':2, - 'HostNetworkInterfaceType_Bridged':1, - 'HostNetworkInterfaceType_HostOnly':2, - 'AdditionsFacilityType_None':0, - 'AdditionsFacilityType_VBoxGuestDriver':20, - 'AdditionsFacilityType_AutoLogon':90, - 'AdditionsFacilityType_VBoxService':100, - 'AdditionsFacilityType_VBoxTrayClient':101, - 'AdditionsFacilityType_Seamless':1000, - 'AdditionsFacilityType_Graphics':1100, - 'AdditionsFacilityType_All':2147483646, - 'AdditionsFacilityClass_None':0, - 'AdditionsFacilityClass_Driver':10, - 'AdditionsFacilityClass_Service':30, - 'AdditionsFacilityClass_Program':50, - 'AdditionsFacilityClass_Feature':100, - 'AdditionsFacilityClass_ThirdParty':999, - 'AdditionsFacilityClass_All':2147483646, - 'AdditionsFacilityStatus_Inactive':0, - 'AdditionsFacilityStatus_Paused':1, - 'AdditionsFacilityStatus_PreInit':20, - 'AdditionsFacilityStatus_Init':30, - 'AdditionsFacilityStatus_Active':50, - 'AdditionsFacilityStatus_Terminating':100, - 'AdditionsFacilityStatus_Terminated':101, - 'AdditionsFacilityStatus_Failed':800, - 'AdditionsFacilityStatus_Unknown':999, - 'AdditionsRunLevelType_None':0, - 'AdditionsRunLevelType_System':1, - 'AdditionsRunLevelType_Userland':2, - 'AdditionsRunLevelType_Desktop':3, - 'AdditionsUpdateFlag_None':0, - 'AdditionsUpdateFlag_WaitForUpdateStartOnly':1, - 'FileSeekType_Set':0, - 'FileSeekType_Current':1, - 'ProcessInputFlag_None':0, - 'ProcessInputFlag_EndOfFile':1, - 'ProcessOutputFlag_None':0, - 'ProcessOutputFlag_StdErr':1, - 'ProcessWaitForFlag_None':0, - 'ProcessWaitForFlag_Start':1, - 'ProcessWaitForFlag_Terminate':2, - 'ProcessWaitForFlag_StdIn':4, - 'ProcessWaitForFlag_StdOut':8, - 'ProcessWaitForFlag_StdErr':16, - 'ProcessWaitResult_None':0, - 'ProcessWaitResult_Start':1, - 'ProcessWaitResult_Terminate':2, - 'ProcessWaitResult_Status':3, - 'ProcessWaitResult_Error':4, - 'ProcessWaitResult_Timeout':5, - 'ProcessWaitResult_StdIn':6, - 'ProcessWaitResult_StdOut':7, - 'ProcessWaitResult_StdErr':8, - 'ProcessWaitResult_WaitFlagNotSupported':9, - 'CopyFileFlag_None':0, - 'CopyFileFlag_Recursive':1, - 'CopyFileFlag_Update':2, - 'CopyFileFlag_FollowLinks':4, - 'DirectoryCreateFlag_None':0, - 'DirectoryCreateFlag_Parents':1, - 'DirectoryRemoveRecFlag_None':0, - 'DirectoryRemoveRecFlag_ContentAndDir':1, - 'DirectoryRemoveRecFlag_ContentOnly':2, - 'PathRenameFlag_None':0, - 'PathRenameFlag_NoReplace':1, - 'PathRenameFlag_Replace':2, - 'PathRenameFlag_NoSymlinks':4, - 'ProcessCreateFlag_None':0, - 'ProcessCreateFlag_WaitForProcessStartOnly':1, - 'ProcessCreateFlag_IgnoreOrphanedProcesses':2, - 'ProcessCreateFlag_Hidden':4, - 'ProcessCreateFlag_NoProfile':8, - 'ProcessCreateFlag_WaitForStdOut':16, - 'ProcessCreateFlag_WaitForStdErr':32, - 'ProcessCreateFlag_ExpandArguments':64, - 'ProcessPriority_Invalid':0, - 'ProcessPriority_Default':1, - 'SymlinkType_Unknown':0, - 'SymlinkType_Directory':1, - 'SymlinkType_File':2, - 'SymlinkReadFlag_None':0, - 'SymlinkReadFlag_NoSymlinks':1, - 'ProcessStatus_Undefined':0, - 'ProcessStatus_Starting':10, - 'ProcessStatus_Started':100, - 'ProcessStatus_Paused':110, - 'ProcessStatus_Terminating':480, - 'ProcessStatus_TerminatedNormally':500, - 'ProcessStatus_TerminatedSignal':510, - 'ProcessStatus_TerminatedAbnormally':511, - 'ProcessStatus_TimedOutKilled':512, - 'ProcessStatus_TimedOutAbnormally':513, - 'ProcessStatus_Down':600, - 'ProcessStatus_Error':800, - 'FsObjType_Undefined':0, - 'FsObjType_FIFO':1, - 'FsObjType_DevChar':10, - 'FsObjType_DevBlock':11, - 'FsObjType_Directory':50, - 'FsObjType_File':80, - 'FsObjType_Symlink':100, - 'FsObjType_Socket':200, - 'FsObjType_Whiteout':400, - 'DragAndDropAction_Ignore':0, - 'DragAndDropAction_Copy':1, - 'DragAndDropAction_Move':2, - 'DragAndDropAction_Link':3, - 'DirectoryOpenFlag_None':0, - 'DirectoryOpenFlag_NoSymlinks':1, - 'MediumState_NotCreated':0, - 'MediumState_Created':1, - 'MediumState_LockedRead':2, - 'MediumState_LockedWrite':3, - 'MediumState_Inaccessible':4, - 'MediumState_Creating':5, - 'MediumState_Deleting':6, - 'MediumType_Normal':0, - 'MediumType_Immutable':1, - 'MediumType_Writethrough':2, - 'MediumType_Shareable':3, - 'MediumType_Readonly':4, - 'MediumType_MultiAttach':5, - 'MediumVariant_Standard':0, - 'MediumVariant_VmdkSplit2G':0x01, - 'MediumVariant_VmdkRawDisk':0x02, - 'MediumVariant_VmdkStreamOptimized':0x04, - 'MediumVariant_VmdkESX':0x08, - 'MediumVariant_Fixed':0x10000, - 'MediumVariant_Diff':0x20000, - 'MediumVariant_NoCreateDir':0x40000000, - 'DataType_Int32':0, - 'DataType_Int8':1, - 'DataType_String':2, - 'DataFlags_None':0x00, - 'DataFlags_Mandatory':0x01, - 'DataFlags_Expert':0x02, - 'DataFlags_Array':0x04, - 'DataFlags_FlagMask':0x07, - 'MediumFormatCapabilities_Uuid':0x01, - 'MediumFormatCapabilities_CreateFixed':0x02, - 'MediumFormatCapabilities_CreateDynamic':0x04, - 'MediumFormatCapabilities_CreateSplit2G':0x08, - 'MediumFormatCapabilities_Differencing':0x10, - 'MediumFormatCapabilities_Asynchronous':0x20, - 'MediumFormatCapabilities_File':0x40, - 'MediumFormatCapabilities_Properties':0x80, - 'MediumFormatCapabilities_TcpNetworking':0x100, - 'MediumFormatCapabilities_VFS':0x200, - 'MediumFormatCapabilities_CapabilityMask':0x3FF, - 'MouseButtonState_LeftButton':0x01, - 'MouseButtonState_RightButton':0x02, - 'MouseButtonState_MiddleButton':0x04, - 'MouseButtonState_WheelUp':0x08, - 'MouseButtonState_WheelDown':0x10, - 'MouseButtonState_XButton1':0x20, - 'MouseButtonState_XButton2':0x40, - 'MouseButtonState_MouseStateMask':0x7F, - 'FramebufferPixelFormat_Opaque':0, - 'FramebufferPixelFormat_FOURCC_RGB':0x32424752, - 'NetworkAttachmentType_Null':0, - 'NetworkAttachmentType_NAT':1, - 'NetworkAttachmentType_Bridged':2, - 'NetworkAttachmentType_Internal':3, - 'NetworkAttachmentType_HostOnly':4, - 'NetworkAttachmentType_Generic':5, - 'NetworkAdapterType_Null':0, - 'NetworkAdapterType_Am79C970A':1, - 'NetworkAdapterType_Am79C973':2, - 'NetworkAdapterType_I82540EM':3, - 'NetworkAdapterType_I82543GC':4, - 'NetworkAdapterType_I82545EM':5, - 'NetworkAdapterType_Virtio':6, - 'NetworkAdapterPromiscModePolicy_Deny':1, - 'NetworkAdapterPromiscModePolicy_AllowNetwork':2, - 'NetworkAdapterPromiscModePolicy_AllowAll':3, - 'PortMode_Disconnected':0, - 'PortMode_HostPipe':1, - 'PortMode_HostDevice':2, - 'PortMode_RawFile':3, - 'USBDeviceState_NotSupported':0, - 'USBDeviceState_Unavailable':1, - 'USBDeviceState_Busy':2, - 'USBDeviceState_Available':3, - 'USBDeviceState_Held':4, - 'USBDeviceState_Captured':5, - 'USBDeviceFilterAction_Null':0, - 'USBDeviceFilterAction_Ignore':1, - 'USBDeviceFilterAction_Hold':2, - 'AudioDriverType_Null':0, - 'AudioDriverType_WinMM':1, - 'AudioDriverType_OSS':2, - 'AudioDriverType_ALSA':3, - 'AudioDriverType_DirectSound':4, - 'AudioDriverType_CoreAudio':5, - 'AudioDriverType_MMPM':6, - 'AudioDriverType_Pulse':7, - 'AudioDriverType_SolAudio':8, - 'AudioControllerType_AC97':0, - 'AudioControllerType_SB16':1, - 'AudioControllerType_HDA':2, - 'AuthType_Null':0, - 'AuthType_External':1, - 'AuthType_Guest':2, - 'StorageBus_Null':0, - 'StorageBus_IDE':1, - 'StorageBus_SATA':2, - 'StorageBus_SCSI':3, - 'StorageBus_Floppy':4, - 'StorageBus_SAS':5, - 'StorageControllerType_Null':0, - 'StorageControllerType_LsiLogic':1, - 'StorageControllerType_BusLogic':2, - 'StorageControllerType_IntelAhci':3, - 'StorageControllerType_PIIX3':4, - 'StorageControllerType_PIIX4':5, - 'StorageControllerType_ICH6':6, - 'StorageControllerType_I82078':7, - 'StorageControllerType_LsiLogicSas':8, - 'ChipsetType_Null':0, - 'ChipsetType_PIIX3':1, - 'ChipsetType_ICH9':2, - 'NATAliasMode_AliasLog':0x1, - 'NATAliasMode_AliasProxyOnly':0x02, - 'NATAliasMode_AliasUseSamePorts':0x04, - 'NATProtocol_UDP':0, - 'NATProtocol_TCP':1, - 'BandwidthGroupType_Null':0, - 'BandwidthGroupType_Disk':1, - 'BandwidthGroupType_Network':2, - 'VBoxEventType_Invalid':0, - 'VBoxEventType_Any':1, - 'VBoxEventType_Vetoable':2, - 'VBoxEventType_MachineEvent':3, - 'VBoxEventType_SnapshotEvent':4, - 'VBoxEventType_InputEvent':5, - 'VBoxEventType_LastWildcard':31, - 'VBoxEventType_OnMachineStateChanged':32, - 'VBoxEventType_OnMachineDataChanged':33, - 'VBoxEventType_OnExtraDataChanged':34, - 'VBoxEventType_OnExtraDataCanChange':35, - 'VBoxEventType_OnMediumRegistered':36, - 'VBoxEventType_OnMachineRegistered':37, - 'VBoxEventType_OnSessionStateChanged':38, - 'VBoxEventType_OnSnapshotTaken':39, - 'VBoxEventType_OnSnapshotDeleted':40, - 'VBoxEventType_OnSnapshotChanged':41, - 'VBoxEventType_OnGuestPropertyChanged':42, - 'VBoxEventType_OnMousePointerShapeChanged':43, - 'VBoxEventType_OnMouseCapabilityChanged':44, - 'VBoxEventType_OnKeyboardLedsChanged':45, - 'VBoxEventType_OnStateChanged':46, - 'VBoxEventType_OnAdditionsStateChanged':47, - 'VBoxEventType_OnNetworkAdapterChanged':48, - 'VBoxEventType_OnSerialPortChanged':49, - 'VBoxEventType_OnParallelPortChanged':50, - 'VBoxEventType_OnStorageControllerChanged':51, - 'VBoxEventType_OnMediumChanged':52, - 'VBoxEventType_OnVRDEServerChanged':53, - 'VBoxEventType_OnUSBControllerChanged':54, - 'VBoxEventType_OnUSBDeviceStateChanged':55, - 'VBoxEventType_OnSharedFolderChanged':56, - 'VBoxEventType_OnRuntimeError':57, - 'VBoxEventType_OnCanShowWindow':58, - 'VBoxEventType_OnShowWindow':59, - 'VBoxEventType_OnCPUChanged':60, - 'VBoxEventType_OnVRDEServerInfoChanged':61, - 'VBoxEventType_OnEventSourceChanged':62, - 'VBoxEventType_OnCPUExecutionCapChanged':63, - 'VBoxEventType_OnGuestKeyboard':64, - 'VBoxEventType_OnGuestMouse':65, - 'VBoxEventType_OnNATRedirect':66, - 'VBoxEventType_OnHostPCIDevicePlug':67, - 'VBoxEventType_OnVBoxSVCAvailabilityChanged':68, - 'VBoxEventType_OnBandwidthGroupChanged':69, - 'VBoxEventType_OnGuestMonitorChanged':70, - 'VBoxEventType_OnStorageDeviceChanged':71, - 'VBoxEventType_OnClipboardModeChanged':72, - 'VBoxEventType_OnDragAndDropModeChanged':73, - 'VBoxEventType_Last':74, - 'GuestMonitorChangedEventType_Enabled':0, - 'GuestMonitorChangedEventType_Disabled':1, - 'GuestMonitorChangedEventType_NewOrigin':2} - - _ValuesFlatSym = { - 'SettingsVersion_Null': 'Null', - 'SettingsVersion_v1_0': 'v1_0', - 'SettingsVersion_v1_1': 'v1_1', - 'SettingsVersion_v1_2': 'v1_2', - 'SettingsVersion_v1_3pre': 'v1_3pre', - 'SettingsVersion_v1_3': 'v1_3', - 'SettingsVersion_v1_4': 'v1_4', - 'SettingsVersion_v1_5': 'v1_5', - 'SettingsVersion_v1_6': 'v1_6', - 'SettingsVersion_v1_7': 'v1_7', - 'SettingsVersion_v1_8': 'v1_8', - 'SettingsVersion_v1_9': 'v1_9', - 'SettingsVersion_v1_10': 'v1_10', - 'SettingsVersion_v1_11': 'v1_11', - 'SettingsVersion_v1_12': 'v1_12', - 'SettingsVersion_v1_13': 'v1_13', - 'SettingsVersion_Future': 'Future', - 'AccessMode_ReadOnly': 'ReadOnly', - 'AccessMode_ReadWrite': 'ReadWrite', - 'MachineState_Null': 'Null', - 'MachineState_PoweredOff': 'PoweredOff', - 'MachineState_Saved': 'Saved', - 'MachineState_Teleported': 'Teleported', - 'MachineState_Aborted': 'Aborted', - 'MachineState_Running': 'Running', - 'MachineState_Paused': 'Paused', - 'MachineState_Stuck': 'Stuck', - 'MachineState_Teleporting': 'Teleporting', - 'MachineState_LiveSnapshotting': 'LiveSnapshotting', - 'MachineState_Starting': 'Starting', - 'MachineState_Stopping': 'Stopping', - 'MachineState_Saving': 'Saving', - 'MachineState_Restoring': 'Restoring', - 'MachineState_TeleportingPausedVM': 'TeleportingPausedVM', - 'MachineState_TeleportingIn': 'TeleportingIn', - 'MachineState_FaultTolerantSyncing': 'FaultTolerantSyncing', - 'MachineState_DeletingSnapshotOnline': 'DeletingSnapshotOnline', - 'MachineState_DeletingSnapshotPaused': 'DeletingSnapshotPaused', - 'MachineState_RestoringSnapshot': 'RestoringSnapshot', - 'MachineState_DeletingSnapshot': 'DeletingSnapshot', - 'MachineState_SettingUp': 'SettingUp', - 'MachineState_FirstOnline': 'FirstOnline', - 'MachineState_LastOnline': 'LastOnline', - 'MachineState_FirstTransient': 'FirstTransient', - 'MachineState_LastTransient': 'LastTransient', - 'SessionState_Null': 'Null', - 'SessionState_Unlocked': 'Unlocked', - 'SessionState_Locked': 'Locked', - 'SessionState_Spawning': 'Spawning', - 'SessionState_Unlocking': 'Unlocking', - 'CPUPropertyType_Null': 'Null', - 'CPUPropertyType_PAE': 'PAE', - 'CPUPropertyType_Synthetic': 'Synthetic', - 'HWVirtExPropertyType_Null': 'Null', - 'HWVirtExPropertyType_Enabled': 'Enabled', - 'HWVirtExPropertyType_Exclusive': 'Exclusive', - 'HWVirtExPropertyType_VPID': 'VPID', - 'HWVirtExPropertyType_NestedPaging': 'NestedPaging', - 'HWVirtExPropertyType_LargePages': 'LargePages', - 'HWVirtExPropertyType_Force': 'Force', - 'FaultToleranceState_Inactive': 'Inactive', - 'FaultToleranceState_Master': 'Master', - 'FaultToleranceState_Standby': 'Standby', - 'LockType_Write': 'Write', - 'LockType_Shared': 'Shared', - 'LockType_VM': 'VM', - 'SessionType_Null': 'Null', - 'SessionType_WriteLock': 'WriteLock', - 'SessionType_Remote': 'Remote', - 'SessionType_Shared': 'Shared', - 'DeviceType_Null': 'Null', - 'DeviceType_Floppy': 'Floppy', - 'DeviceType_DVD': 'DVD', - 'DeviceType_HardDisk': 'HardDisk', - 'DeviceType_Network': 'Network', - 'DeviceType_USB': 'USB', - 'DeviceType_SharedFolder': 'SharedFolder', - 'DeviceActivity_Null': 'Null', - 'DeviceActivity_Idle': 'Idle', - 'DeviceActivity_Reading': 'Reading', - 'DeviceActivity_Writing': 'Writing', - 'ClipboardMode_Disabled': 'Disabled', - 'ClipboardMode_HostToGuest': 'HostToGuest', - 'ClipboardMode_GuestToHost': 'GuestToHost', - 'ClipboardMode_Bidirectional': 'Bidirectional', - 'DragAndDropMode_Disabled': 'Disabled', - 'DragAndDropMode_HostToGuest': 'HostToGuest', - 'DragAndDropMode_GuestToHost': 'GuestToHost', - 'DragAndDropMode_Bidirectional': 'Bidirectional', - 'Scope_Global': 'Global', - 'Scope_Machine': 'Machine', - 'Scope_Session': 'Session', - 'BIOSBootMenuMode_Disabled': 'Disabled', - 'BIOSBootMenuMode_MenuOnly': 'MenuOnly', - 'BIOSBootMenuMode_MessageAndMenu': 'MessageAndMenu', - 'ProcessorFeature_HWVirtEx': 'HWVirtEx', - 'ProcessorFeature_PAE': 'PAE', - 'ProcessorFeature_LongMode': 'LongMode', - 'ProcessorFeature_NestedPaging': 'NestedPaging', - 'FirmwareType_BIOS': 'BIOS', - 'FirmwareType_EFI': 'EFI', - 'FirmwareType_EFI32': 'EFI32', - 'FirmwareType_EFI64': 'EFI64', - 'FirmwareType_EFIDUAL': 'EFIDUAL', - 'PointingHIDType_None': 'None', - 'PointingHIDType_PS2Mouse': 'PS2Mouse', - 'PointingHIDType_USBMouse': 'USBMouse', - 'PointingHIDType_USBTablet': 'USBTablet', - 'PointingHIDType_ComboMouse': 'ComboMouse', - 'KeyboardHIDType_None': 'None', - 'KeyboardHIDType_PS2Keyboard': 'PS2Keyboard', - 'KeyboardHIDType_USBKeyboard': 'USBKeyboard', - 'KeyboardHIDType_ComboKeyboard': 'ComboKeyboard', - 'VFSType_File': 'File', - 'VFSType_Cloud': 'Cloud', - 'VFSType_S3': 'S3', - 'VFSType_WebDav': 'WebDav', - 'VFSFileType_Unknown': 'Unknown', - 'VFSFileType_Fifo': 'Fifo', - 'VFSFileType_DevChar': 'DevChar', - 'VFSFileType_Directory': 'Directory', - 'VFSFileType_DevBlock': 'DevBlock', - 'VFSFileType_File': 'File', - 'VFSFileType_SymLink': 'SymLink', - 'VFSFileType_Socket': 'Socket', - 'VFSFileType_WhiteOut': 'WhiteOut', - 'ImportOptions_KeepAllMACs': 'KeepAllMACs', - 'ImportOptions_KeepNATMACs': 'KeepNATMACs', - 'VirtualSystemDescriptionType_Ignore': 'Ignore', - 'VirtualSystemDescriptionType_OS': 'OS', - 'VirtualSystemDescriptionType_Name': 'Name', - 'VirtualSystemDescriptionType_Product': 'Product', - 'VirtualSystemDescriptionType_Vendor': 'Vendor', - 'VirtualSystemDescriptionType_Version': 'Version', - 'VirtualSystemDescriptionType_ProductUrl': 'ProductUrl', - 'VirtualSystemDescriptionType_VendorUrl': 'VendorUrl', - 'VirtualSystemDescriptionType_Description': 'Description', - 'VirtualSystemDescriptionType_License': 'License', - 'VirtualSystemDescriptionType_Miscellaneous': 'Miscellaneous', - 'VirtualSystemDescriptionType_CPU': 'CPU', - 'VirtualSystemDescriptionType_Memory': 'Memory', - 'VirtualSystemDescriptionType_HardDiskControllerIDE': 'HardDiskControllerIDE', - 'VirtualSystemDescriptionType_HardDiskControllerSATA': 'HardDiskControllerSATA', - 'VirtualSystemDescriptionType_HardDiskControllerSCSI': 'HardDiskControllerSCSI', - 'VirtualSystemDescriptionType_HardDiskControllerSAS': 'HardDiskControllerSAS', - 'VirtualSystemDescriptionType_HardDiskImage': 'HardDiskImage', - 'VirtualSystemDescriptionType_Floppy': 'Floppy', - 'VirtualSystemDescriptionType_CDROM': 'CDROM', - 'VirtualSystemDescriptionType_NetworkAdapter': 'NetworkAdapter', - 'VirtualSystemDescriptionType_USBController': 'USBController', - 'VirtualSystemDescriptionType_SoundCard': 'SoundCard', - 'VirtualSystemDescriptionType_SettingsFile': 'SettingsFile', - 'VirtualSystemDescriptionValueType_Reference': 'Reference', - 'VirtualSystemDescriptionValueType_Original': 'Original', - 'VirtualSystemDescriptionValueType_Auto': 'Auto', - 'VirtualSystemDescriptionValueType_ExtraConfig': 'ExtraConfig', - 'CleanupMode_UnregisterOnly': 'UnregisterOnly', - 'CleanupMode_DetachAllReturnNone': 'DetachAllReturnNone', - 'CleanupMode_DetachAllReturnHardDisksOnly': 'DetachAllReturnHardDisksOnly', - 'CleanupMode_Full': 'Full', - 'CloneMode_MachineState': 'MachineState', - 'CloneMode_MachineAndChildStates': 'MachineAndChildStates', - 'CloneMode_AllStates': 'AllStates', - 'CloneOptions_Link': 'Link', - 'CloneOptions_KeepAllMACs': 'KeepAllMACs', - 'CloneOptions_KeepNATMACs': 'KeepNATMACs', - 'CloneOptions_KeepDiskNames': 'KeepDiskNames', - 'AutostopType_Disabled': 'Disabled', - 'AutostopType_SaveState': 'SaveState', - 'AutostopType_PowerOff': 'PowerOff', - 'AutostopType_AcpiShutdown': 'AcpiShutdown', - 'HostNetworkInterfaceMediumType_Unknown': 'Unknown', - 'HostNetworkInterfaceMediumType_Ethernet': 'Ethernet', - 'HostNetworkInterfaceMediumType_PPP': 'PPP', - 'HostNetworkInterfaceMediumType_SLIP': 'SLIP', - 'HostNetworkInterfaceStatus_Unknown': 'Unknown', - 'HostNetworkInterfaceStatus_Up': 'Up', - 'HostNetworkInterfaceStatus_Down': 'Down', - 'HostNetworkInterfaceType_Bridged': 'Bridged', - 'HostNetworkInterfaceType_HostOnly': 'HostOnly', - 'AdditionsFacilityType_None': 'None', - 'AdditionsFacilityType_VBoxGuestDriver': 'VBoxGuestDriver', - 'AdditionsFacilityType_AutoLogon': 'AutoLogon', - 'AdditionsFacilityType_VBoxService': 'VBoxService', - 'AdditionsFacilityType_VBoxTrayClient': 'VBoxTrayClient', - 'AdditionsFacilityType_Seamless': 'Seamless', - 'AdditionsFacilityType_Graphics': 'Graphics', - 'AdditionsFacilityType_All': 'All', - 'AdditionsFacilityClass_None': 'None', - 'AdditionsFacilityClass_Driver': 'Driver', - 'AdditionsFacilityClass_Service': 'Service', - 'AdditionsFacilityClass_Program': 'Program', - 'AdditionsFacilityClass_Feature': 'Feature', - 'AdditionsFacilityClass_ThirdParty': 'ThirdParty', - 'AdditionsFacilityClass_All': 'All', - 'AdditionsFacilityStatus_Inactive': 'Inactive', - 'AdditionsFacilityStatus_Paused': 'Paused', - 'AdditionsFacilityStatus_PreInit': 'PreInit', - 'AdditionsFacilityStatus_Init': 'Init', - 'AdditionsFacilityStatus_Active': 'Active', - 'AdditionsFacilityStatus_Terminating': 'Terminating', - 'AdditionsFacilityStatus_Terminated': 'Terminated', - 'AdditionsFacilityStatus_Failed': 'Failed', - 'AdditionsFacilityStatus_Unknown': 'Unknown', - 'AdditionsRunLevelType_None': 'None', - 'AdditionsRunLevelType_System': 'System', - 'AdditionsRunLevelType_Userland': 'Userland', - 'AdditionsRunLevelType_Desktop': 'Desktop', - 'AdditionsUpdateFlag_None': 'None', - 'AdditionsUpdateFlag_WaitForUpdateStartOnly': 'WaitForUpdateStartOnly', - 'FileSeekType_Set': 'Set', - 'FileSeekType_Current': 'Current', - 'ProcessInputFlag_None': 'None', - 'ProcessInputFlag_EndOfFile': 'EndOfFile', - 'ProcessOutputFlag_None': 'None', - 'ProcessOutputFlag_StdErr': 'StdErr', - 'ProcessWaitForFlag_None': 'None', - 'ProcessWaitForFlag_Start': 'Start', - 'ProcessWaitForFlag_Terminate': 'Terminate', - 'ProcessWaitForFlag_StdIn': 'StdIn', - 'ProcessWaitForFlag_StdOut': 'StdOut', - 'ProcessWaitForFlag_StdErr': 'StdErr', - 'ProcessWaitResult_None': 'None', - 'ProcessWaitResult_Start': 'Start', - 'ProcessWaitResult_Terminate': 'Terminate', - 'ProcessWaitResult_Status': 'Status', - 'ProcessWaitResult_Error': 'Error', - 'ProcessWaitResult_Timeout': 'Timeout', - 'ProcessWaitResult_StdIn': 'StdIn', - 'ProcessWaitResult_StdOut': 'StdOut', - 'ProcessWaitResult_StdErr': 'StdErr', - 'ProcessWaitResult_WaitFlagNotSupported': 'WaitFlagNotSupported', - 'CopyFileFlag_None': 'None', - 'CopyFileFlag_Recursive': 'Recursive', - 'CopyFileFlag_Update': 'Update', - 'CopyFileFlag_FollowLinks': 'FollowLinks', - 'DirectoryCreateFlag_None': 'None', - 'DirectoryCreateFlag_Parents': 'Parents', - 'DirectoryRemoveRecFlag_None': 'None', - 'DirectoryRemoveRecFlag_ContentAndDir': 'ContentAndDir', - 'DirectoryRemoveRecFlag_ContentOnly': 'ContentOnly', - 'PathRenameFlag_None': 'None', - 'PathRenameFlag_NoReplace': 'NoReplace', - 'PathRenameFlag_Replace': 'Replace', - 'PathRenameFlag_NoSymlinks': 'NoSymlinks', - 'ProcessCreateFlag_None': 'None', - 'ProcessCreateFlag_WaitForProcessStartOnly': 'WaitForProcessStartOnly', - 'ProcessCreateFlag_IgnoreOrphanedProcesses': 'IgnoreOrphanedProcesses', - 'ProcessCreateFlag_Hidden': 'Hidden', - 'ProcessCreateFlag_NoProfile': 'NoProfile', - 'ProcessCreateFlag_WaitForStdOut': 'WaitForStdOut', - 'ProcessCreateFlag_WaitForStdErr': 'WaitForStdErr', - 'ProcessCreateFlag_ExpandArguments': 'ExpandArguments', - 'ProcessPriority_Invalid': 'Invalid', - 'ProcessPriority_Default': 'Default', - 'SymlinkType_Unknown': 'Unknown', - 'SymlinkType_Directory': 'Directory', - 'SymlinkType_File': 'File', - 'SymlinkReadFlag_None': 'None', - 'SymlinkReadFlag_NoSymlinks': 'NoSymlinks', - 'ProcessStatus_Undefined': 'Undefined', - 'ProcessStatus_Starting': 'Starting', - 'ProcessStatus_Started': 'Started', - 'ProcessStatus_Paused': 'Paused', - 'ProcessStatus_Terminating': 'Terminating', - 'ProcessStatus_TerminatedNormally': 'TerminatedNormally', - 'ProcessStatus_TerminatedSignal': 'TerminatedSignal', - 'ProcessStatus_TerminatedAbnormally': 'TerminatedAbnormally', - 'ProcessStatus_TimedOutKilled': 'TimedOutKilled', - 'ProcessStatus_TimedOutAbnormally': 'TimedOutAbnormally', - 'ProcessStatus_Down': 'Down', - 'ProcessStatus_Error': 'Error', - 'FsObjType_Undefined': 'Undefined', - 'FsObjType_FIFO': 'FIFO', - 'FsObjType_DevChar': 'DevChar', - 'FsObjType_DevBlock': 'DevBlock', - 'FsObjType_Directory': 'Directory', - 'FsObjType_File': 'File', - 'FsObjType_Symlink': 'Symlink', - 'FsObjType_Socket': 'Socket', - 'FsObjType_Whiteout': 'Whiteout', - 'DragAndDropAction_Ignore': 'Ignore', - 'DragAndDropAction_Copy': 'Copy', - 'DragAndDropAction_Move': 'Move', - 'DragAndDropAction_Link': 'Link', - 'DirectoryOpenFlag_None': 'None', - 'DirectoryOpenFlag_NoSymlinks': 'NoSymlinks', - 'MediumState_NotCreated': 'NotCreated', - 'MediumState_Created': 'Created', - 'MediumState_LockedRead': 'LockedRead', - 'MediumState_LockedWrite': 'LockedWrite', - 'MediumState_Inaccessible': 'Inaccessible', - 'MediumState_Creating': 'Creating', - 'MediumState_Deleting': 'Deleting', - 'MediumType_Normal': 'Normal', - 'MediumType_Immutable': 'Immutable', - 'MediumType_Writethrough': 'Writethrough', - 'MediumType_Shareable': 'Shareable', - 'MediumType_Readonly': 'Readonly', - 'MediumType_MultiAttach': 'MultiAttach', - 'MediumVariant_Standard': 'Standard', - 'MediumVariant_VmdkSplit2G': 'VmdkSplit2G', - 'MediumVariant_VmdkRawDisk': 'VmdkRawDisk', - 'MediumVariant_VmdkStreamOptimized': 'VmdkStreamOptimized', - 'MediumVariant_VmdkESX': 'VmdkESX', - 'MediumVariant_Fixed': 'Fixed', - 'MediumVariant_Diff': 'Diff', - 'MediumVariant_NoCreateDir': 'NoCreateDir', - 'DataType_Int32': 'Int32', - 'DataType_Int8': 'Int8', - 'DataType_String': 'String', - 'DataFlags_None': 'None', - 'DataFlags_Mandatory': 'Mandatory', - 'DataFlags_Expert': 'Expert', - 'DataFlags_Array': 'Array', - 'DataFlags_FlagMask': 'FlagMask', - 'MediumFormatCapabilities_Uuid': 'Uuid', - 'MediumFormatCapabilities_CreateFixed': 'CreateFixed', - 'MediumFormatCapabilities_CreateDynamic': 'CreateDynamic', - 'MediumFormatCapabilities_CreateSplit2G': 'CreateSplit2G', - 'MediumFormatCapabilities_Differencing': 'Differencing', - 'MediumFormatCapabilities_Asynchronous': 'Asynchronous', - 'MediumFormatCapabilities_File': 'File', - 'MediumFormatCapabilities_Properties': 'Properties', - 'MediumFormatCapabilities_TcpNetworking': 'TcpNetworking', - 'MediumFormatCapabilities_VFS': 'VFS', - 'MediumFormatCapabilities_CapabilityMask': 'CapabilityMask', - 'MouseButtonState_LeftButton': 'LeftButton', - 'MouseButtonState_RightButton': 'RightButton', - 'MouseButtonState_MiddleButton': 'MiddleButton', - 'MouseButtonState_WheelUp': 'WheelUp', - 'MouseButtonState_WheelDown': 'WheelDown', - 'MouseButtonState_XButton1': 'XButton1', - 'MouseButtonState_XButton2': 'XButton2', - 'MouseButtonState_MouseStateMask': 'MouseStateMask', - 'FramebufferPixelFormat_Opaque': 'Opaque', - 'FramebufferPixelFormat_FOURCC_RGB': 'FOURCC_RGB', - 'NetworkAttachmentType_Null': 'Null', - 'NetworkAttachmentType_NAT': 'NAT', - 'NetworkAttachmentType_Bridged': 'Bridged', - 'NetworkAttachmentType_Internal': 'Internal', - 'NetworkAttachmentType_HostOnly': 'HostOnly', - 'NetworkAttachmentType_Generic': 'Generic', - 'NetworkAdapterType_Null': 'Null', - 'NetworkAdapterType_Am79C970A': 'Am79C970A', - 'NetworkAdapterType_Am79C973': 'Am79C973', - 'NetworkAdapterType_I82540EM': 'I82540EM', - 'NetworkAdapterType_I82543GC': 'I82543GC', - 'NetworkAdapterType_I82545EM': 'I82545EM', - 'NetworkAdapterType_Virtio': 'Virtio', - 'NetworkAdapterPromiscModePolicy_Deny': 'Deny', - 'NetworkAdapterPromiscModePolicy_AllowNetwork': 'AllowNetwork', - 'NetworkAdapterPromiscModePolicy_AllowAll': 'AllowAll', - 'PortMode_Disconnected': 'Disconnected', - 'PortMode_HostPipe': 'HostPipe', - 'PortMode_HostDevice': 'HostDevice', - 'PortMode_RawFile': 'RawFile', - 'USBDeviceState_NotSupported': 'NotSupported', - 'USBDeviceState_Unavailable': 'Unavailable', - 'USBDeviceState_Busy': 'Busy', - 'USBDeviceState_Available': 'Available', - 'USBDeviceState_Held': 'Held', - 'USBDeviceState_Captured': 'Captured', - 'USBDeviceFilterAction_Null': 'Null', - 'USBDeviceFilterAction_Ignore': 'Ignore', - 'USBDeviceFilterAction_Hold': 'Hold', - 'AudioDriverType_Null': 'Null', - 'AudioDriverType_WinMM': 'WinMM', - 'AudioDriverType_OSS': 'OSS', - 'AudioDriverType_ALSA': 'ALSA', - 'AudioDriverType_DirectSound': 'DirectSound', - 'AudioDriverType_CoreAudio': 'CoreAudio', - 'AudioDriverType_MMPM': 'MMPM', - 'AudioDriverType_Pulse': 'Pulse', - 'AudioDriverType_SolAudio': 'SolAudio', - 'AudioControllerType_AC97': 'AC97', - 'AudioControllerType_SB16': 'SB16', - 'AudioControllerType_HDA': 'HDA', - 'AuthType_Null': 'Null', - 'AuthType_External': 'External', - 'AuthType_Guest': 'Guest', - 'StorageBus_Null': 'Null', - 'StorageBus_IDE': 'IDE', - 'StorageBus_SATA': 'SATA', - 'StorageBus_SCSI': 'SCSI', - 'StorageBus_Floppy': 'Floppy', - 'StorageBus_SAS': 'SAS', - 'StorageControllerType_Null': 'Null', - 'StorageControllerType_LsiLogic': 'LsiLogic', - 'StorageControllerType_BusLogic': 'BusLogic', - 'StorageControllerType_IntelAhci': 'IntelAhci', - 'StorageControllerType_PIIX3': 'PIIX3', - 'StorageControllerType_PIIX4': 'PIIX4', - 'StorageControllerType_ICH6': 'ICH6', - 'StorageControllerType_I82078': 'I82078', - 'StorageControllerType_LsiLogicSas': 'LsiLogicSas', - 'ChipsetType_Null': 'Null', - 'ChipsetType_PIIX3': 'PIIX3', - 'ChipsetType_ICH9': 'ICH9', - 'NATAliasMode_AliasLog': 'AliasLog', - 'NATAliasMode_AliasProxyOnly': 'AliasProxyOnly', - 'NATAliasMode_AliasUseSamePorts': 'AliasUseSamePorts', - 'NATProtocol_UDP': 'UDP', - 'NATProtocol_TCP': 'TCP', - 'BandwidthGroupType_Null': 'Null', - 'BandwidthGroupType_Disk': 'Disk', - 'BandwidthGroupType_Network': 'Network', - 'VBoxEventType_Invalid': 'Invalid', - 'VBoxEventType_Any': 'Any', - 'VBoxEventType_Vetoable': 'Vetoable', - 'VBoxEventType_MachineEvent': 'MachineEvent', - 'VBoxEventType_SnapshotEvent': 'SnapshotEvent', - 'VBoxEventType_InputEvent': 'InputEvent', - 'VBoxEventType_LastWildcard': 'LastWildcard', - 'VBoxEventType_OnMachineStateChanged': 'OnMachineStateChanged', - 'VBoxEventType_OnMachineDataChanged': 'OnMachineDataChanged', - 'VBoxEventType_OnExtraDataChanged': 'OnExtraDataChanged', - 'VBoxEventType_OnExtraDataCanChange': 'OnExtraDataCanChange', - 'VBoxEventType_OnMediumRegistered': 'OnMediumRegistered', - 'VBoxEventType_OnMachineRegistered': 'OnMachineRegistered', - 'VBoxEventType_OnSessionStateChanged': 'OnSessionStateChanged', - 'VBoxEventType_OnSnapshotTaken': 'OnSnapshotTaken', - 'VBoxEventType_OnSnapshotDeleted': 'OnSnapshotDeleted', - 'VBoxEventType_OnSnapshotChanged': 'OnSnapshotChanged', - 'VBoxEventType_OnGuestPropertyChanged': 'OnGuestPropertyChanged', - 'VBoxEventType_OnMousePointerShapeChanged': 'OnMousePointerShapeChanged', - 'VBoxEventType_OnMouseCapabilityChanged': 'OnMouseCapabilityChanged', - 'VBoxEventType_OnKeyboardLedsChanged': 'OnKeyboardLedsChanged', - 'VBoxEventType_OnStateChanged': 'OnStateChanged', - 'VBoxEventType_OnAdditionsStateChanged': 'OnAdditionsStateChanged', - 'VBoxEventType_OnNetworkAdapterChanged': 'OnNetworkAdapterChanged', - 'VBoxEventType_OnSerialPortChanged': 'OnSerialPortChanged', - 'VBoxEventType_OnParallelPortChanged': 'OnParallelPortChanged', - 'VBoxEventType_OnStorageControllerChanged': 'OnStorageControllerChanged', - 'VBoxEventType_OnMediumChanged': 'OnMediumChanged', - 'VBoxEventType_OnVRDEServerChanged': 'OnVRDEServerChanged', - 'VBoxEventType_OnUSBControllerChanged': 'OnUSBControllerChanged', - 'VBoxEventType_OnUSBDeviceStateChanged': 'OnUSBDeviceStateChanged', - 'VBoxEventType_OnSharedFolderChanged': 'OnSharedFolderChanged', - 'VBoxEventType_OnRuntimeError': 'OnRuntimeError', - 'VBoxEventType_OnCanShowWindow': 'OnCanShowWindow', - 'VBoxEventType_OnShowWindow': 'OnShowWindow', - 'VBoxEventType_OnCPUChanged': 'OnCPUChanged', - 'VBoxEventType_OnVRDEServerInfoChanged': 'OnVRDEServerInfoChanged', - 'VBoxEventType_OnEventSourceChanged': 'OnEventSourceChanged', - 'VBoxEventType_OnCPUExecutionCapChanged': 'OnCPUExecutionCapChanged', - 'VBoxEventType_OnGuestKeyboard': 'OnGuestKeyboard', - 'VBoxEventType_OnGuestMouse': 'OnGuestMouse', - 'VBoxEventType_OnNATRedirect': 'OnNATRedirect', - 'VBoxEventType_OnHostPCIDevicePlug': 'OnHostPCIDevicePlug', - 'VBoxEventType_OnVBoxSVCAvailabilityChanged': 'OnVBoxSVCAvailabilityChanged', - 'VBoxEventType_OnBandwidthGroupChanged': 'OnBandwidthGroupChanged', - 'VBoxEventType_OnGuestMonitorChanged': 'OnGuestMonitorChanged', - 'VBoxEventType_OnStorageDeviceChanged': 'OnStorageDeviceChanged', - 'VBoxEventType_OnClipboardModeChanged': 'OnClipboardModeChanged', - 'VBoxEventType_OnDragAndDropModeChanged': 'OnDragAndDropModeChanged', - 'VBoxEventType_Last': 'Last', - 'GuestMonitorChangedEventType_Enabled': 'Enabled', - 'GuestMonitorChangedEventType_Disabled': 'Disabled', - 'GuestMonitorChangedEventType_NewOrigin': 'NewOrigin'} - - def __getattr__(self,attr): - if self.isSym: - v = self._ValuesFlatSym.get(attr) - else: - v = self._ValuesFlat.get(attr) - if v is not None: - return v - else: - raise AttributeError - - def all_values(self,enum_name): - if self.isSym: - vals = self._ValuesSym.get(enum_name) - else: - vals = self._Values.get(enum_name) - if vals is not None: - return vals - else: - return {} diff --git a/gns3server/modules/virtualbox/vboxapi_py3/__init__.py b/gns3server/modules/virtualbox/vboxapi_py3/__init__.py deleted file mode 100644 index fa25d452..00000000 --- a/gns3server/modules/virtualbox/vboxapi_py3/__init__.py +++ /dev/null @@ -1,612 +0,0 @@ -""" -Copyright (C) 2009-2012 Oracle Corporation - -This file is part of VirtualBox Open Source Edition (OSE), as -available from http://www.virtualbox.org. This file is free software; -you can redistribute it and/or modify it under the terms of the GNU -General Public License (GPL) as published by the Free Software -Foundation, in version 2 as it comes in the "COPYING" file of the -VirtualBox OSE distribution. VirtualBox OSE is distributed in the -hope that it will be useful, but WITHOUT ANY WARRANTY of any kind. -""" - -import sys,os -import traceback - -# To set Python bitness on OSX use 'export VERSIONER_PYTHON_PREFER_32_BIT=yes' - -VboxBinDir = os.environ.get("VBOX_PROGRAM_PATH", None) -VboxSdkDir = os.environ.get("VBOX_SDK_PATH", None) - -if VboxBinDir is None: - # Will be set by the installer - VboxBinDir = "C:\\Program Files\\Oracle\\VirtualBox\\" - -if VboxSdkDir is None: - # Will be set by the installer - VboxSdkDir = "C:\\Program Files\\Oracle\\VirtualBox\\sdk\\" - -os.environ["VBOX_PROGRAM_PATH"] = VboxBinDir -os.environ["VBOX_SDK_PATH"] = VboxSdkDir -sys.path.append(VboxBinDir) - -from .VirtualBox_constants import VirtualBoxReflectionInfo - -class PerfCollector: - """ This class provides a wrapper over IPerformanceCollector in order to - get more 'pythonic' interface. - - To begin collection of metrics use setup() method. - - To get collected data use query() method. - - It is possible to disable metric collection without changing collection - parameters with disable() method. The enable() method resumes metric - collection. - """ - - def __init__(self, mgr, vbox): - """ Initializes the instance. - - """ - self.mgr = mgr - self.isMscom = (mgr.type == 'MSCOM') - self.collector = vbox.performanceCollector - - def setup(self, names, objects, period, nsamples): - """ Discards all previously collected values for the specified - metrics, sets the period of collection and the number of retained - samples, enables collection. - """ - self.collector.setupMetrics(names, objects, period, nsamples) - - def enable(self, names, objects): - """ Resumes metric collection for the specified metrics. - """ - self.collector.enableMetrics(names, objects) - - def disable(self, names, objects): - """ Suspends metric collection for the specified metrics. - """ - self.collector.disableMetrics(names, objects) - - def query(self, names, objects): - """ Retrieves collected metric values as well as some auxiliary - information. Returns an array of dictionaries, one dictionary per - metric. Each dictionary contains the following entries: - 'name': metric name - 'object': managed object this metric associated with - 'unit': unit of measurement - 'scale': divide 'values' by this number to get float numbers - 'values': collected data - 'values_as_string': pre-processed values ready for 'print' statement - """ - # Get around the problem with input arrays returned in output - # parameters (see #3953) for MSCOM. - if self.isMscom: - (values, names, objects, names_out, objects_out, units, scales, sequence_numbers, - indices, lengths) = self.collector.queryMetricsData(names, objects) - else: - (values, names_out, objects_out, units, scales, sequence_numbers, - indices, lengths) = self.collector.queryMetricsData(names, objects) - out = [] - for i in xrange(0, len(names_out)): - scale = int(scales[i]) - if scale != 1: - fmt = '%.2f%s' - else: - fmt = '%d %s' - out.append({ - 'name':str(names_out[i]), - 'object':str(objects_out[i]), - 'unit':str(units[i]), - 'scale':scale, - 'values':[int(values[j]) for j in xrange(int(indices[i]), int(indices[i])+int(lengths[i]))], - 'values_as_string':'['+', '.join([fmt % (int(values[j])/scale, units[i]) for j in xrange(int(indices[i]), int(indices[i])+int(lengths[i]))])+']' - }) - return out - -def ComifyName(name): - return name[0].capitalize()+name[1:] - -_COMForward = { 'getattr' : None, - 'setattr' : None} - -def CustomGetAttr(self, attr): - # fastpath - if self.__class__.__dict__.get(attr) != None: - return self.__class__.__dict__.get(attr) - - # try case-insensitivity workaround for class attributes (COM methods) - for k in self.__class__.__dict__.keys(): - if k.lower() == attr.lower(): - setattr(self.__class__, attr, self.__class__.__dict__[k]) - return getattr(self, k) - try: - return _COMForward['getattr'](self,ComifyName(attr)) - except AttributeError: - return _COMForward['getattr'](self,attr) - -def CustomSetAttr(self, attr, value): - try: - return _COMForward['setattr'](self, ComifyName(attr), value) - except AttributeError: - return _COMForward['setattr'](self, attr, value) - -class PlatformMSCOM: - # Class to fake access to constants in style of foo.bar.boo - class ConstantFake: - def __init__(self, parent, name): - self.__dict__['_parent'] = parent - self.__dict__['_name'] = name - self.__dict__['_consts'] = {} - try: - self.__dict__['_depth']=parent.__dict__['_depth']+1 - except: - self.__dict__['_depth']=0 - if self.__dict__['_depth'] > 4: - raise AttributeError - - def __getattr__(self, attr): - import win32com - from win32com.client import constants - - if attr.startswith("__"): - raise AttributeError - - consts = self.__dict__['_consts'] - - fake = consts.get(attr, None) - if fake != None: - return fake - try: - name = self.__dict__['_name'] - parent = self.__dict__['_parent'] - while parent != None: - if parent._name is not None: - name = parent._name+'_'+name - parent = parent._parent - - if name is not None: - name += "_" + attr - else: - name = attr - return win32com.client.constants.__getattr__(name) - except AttributeError as e: - fake = PlatformMSCOM.ConstantFake(self, attr) - consts[attr] = fake - return fake - - - class InterfacesWrapper: - def __init__(self): - self.__dict__['_rootFake'] = PlatformMSCOM.ConstantFake(None, None) - - def __getattr__(self, a): - import win32com - from win32com.client import constants - if a.startswith("__"): - raise AttributeError - try: - return win32com.client.constants.__getattr__(a) - except AttributeError as e: - return self.__dict__['_rootFake'].__getattr__(a) - - VBOX_TLB_GUID = '{46137EEC-703B-4FE5-AFD4-7C9BBBBA0259}' - VBOX_TLB_LCID = 0 - VBOX_TLB_MAJOR = 1 - VBOX_TLB_MINOR = 0 - - def __init__(self, params): - from win32com import universal - from win32com.client import gencache, DispatchBaseClass - from win32com.client import constants, getevents - import win32com - import pythoncom - import win32api - from win32con import DUPLICATE_SAME_ACCESS - from win32api import GetCurrentThread,GetCurrentThreadId,DuplicateHandle,GetCurrentProcess - import threading - pid = GetCurrentProcess() - self.tid = GetCurrentThreadId() - handle = DuplicateHandle(pid, GetCurrentThread(), pid, 0, 0, DUPLICATE_SAME_ACCESS) - self.handles = [] - self.handles.append(handle) - _COMForward['getattr'] = DispatchBaseClass.__dict__['__getattr__'] - DispatchBaseClass.__getattr__ = CustomGetAttr - _COMForward['setattr'] = DispatchBaseClass.__dict__['__setattr__'] - DispatchBaseClass.__setattr__ = CustomSetAttr - win32com.client.gencache.EnsureDispatch('VirtualBox.Session') - win32com.client.gencache.EnsureDispatch('VirtualBox.VirtualBox') - self.oIntCv = threading.Condition() - self.fInterrupted = False; - - def getSessionObject(self, vbox): - import win32com - from win32com.client import Dispatch - return win32com.client.Dispatch("VirtualBox.Session") - - def getVirtualBox(self): - import win32com - from win32com.client import Dispatch - return win32com.client.Dispatch("VirtualBox.VirtualBox") - - def getType(self): - return 'MSCOM' - - def getRemote(self): - return False - - def getArray(self, obj, field): - return obj.__getattr__(field) - - def initPerThread(self): - import pythoncom - pythoncom.CoInitializeEx(0) - - def deinitPerThread(self): - import pythoncom - pythoncom.CoUninitialize() - - def createListener(self, impl, arg): - d = {} - d['BaseClass'] = impl - d['arg'] = arg - d['tlb_guid'] = PlatformMSCOM.VBOX_TLB_GUID - str = "" - str += "import win32com.server.util\n" - str += "import pythoncom\n" - - str += "class ListenerImpl(BaseClass):\n" - str += " _com_interfaces_ = ['IEventListener']\n" - str += " _typelib_guid_ = tlb_guid\n" - str += " _typelib_version_ = 1, 0\n" - str += " _reg_clsctx_ = pythoncom.CLSCTX_INPROC_SERVER\n" - # Maybe we'd better implement Dynamic invoke policy, to be more flexible here - str += " _reg_policy_spec_ = 'win32com.server.policy.EventHandlerPolicy'\n" - - # capitalized version of listener method - str += " HandleEvent=BaseClass.handleEvent\n" - str += " def __init__(self): BaseClass.__init__(self, arg)\n" - str += "result = win32com.server.util.wrap(ListenerImpl())\n" - exec(str,d,d) - return d['result'] - - def waitForEvents(self, timeout): - from win32api import GetCurrentThreadId - from win32event import INFINITE - from win32event import MsgWaitForMultipleObjects, \ - QS_ALLINPUT, WAIT_TIMEOUT, WAIT_OBJECT_0 - from pythoncom import PumpWaitingMessages - import types - - if not isinstance(timeout, types.IntType): - raise TypeError("The timeout argument is not an integer") - if (self.tid != GetCurrentThreadId()): - raise Exception("wait for events from the same thread you inited!") - - if timeout < 0: cMsTimeout = INFINITE - else: cMsTimeout = timeout - rc = MsgWaitForMultipleObjects(self.handles, 0, cMsTimeout, QS_ALLINPUT) - if rc >= WAIT_OBJECT_0 and rc < WAIT_OBJECT_0+len(self.handles): - # is it possible? - rc = 2; - elif rc==WAIT_OBJECT_0 + len(self.handles): - # Waiting messages - PumpWaitingMessages() - rc = 0; - else: - # Timeout - rc = 1; - - # check for interruption - self.oIntCv.acquire() - if self.fInterrupted: - self.fInterrupted = False - rc = 1; - self.oIntCv.release() - - return rc; - - def interruptWaitEvents(self): - """ - Basically a python implementation of EventQueue::postEvent(). - - The magic value must be in sync with the C++ implementation or this - won't work. - - Note that because of this method we cannot easily make use of a - non-visible Window to handle the message like we would like to do. - """ - from win32api import PostThreadMessage - from win32con import WM_USER - self.oIntCv.acquire() - self.fInterrupted = True - self.oIntCv.release() - try: - PostThreadMessage(self.tid, WM_USER, None, 0xf241b819) - except: - return False; - return True; - - def deinit(self): - import pythoncom - from win32file import CloseHandle - - for h in self.handles: - if h is not None: - CloseHandle(h) - self.handles = None - pythoncom.CoUninitialize() - pass - - def queryInterface(self, obj, klazzName): - from win32com.client import CastTo - return CastTo(obj, klazzName) - -class PlatformXPCOM: - def __init__(self, params): - sys.path.append(VboxSdkDir+'/bindings/xpcom/python/') - import xpcom.vboxxpcom - import xpcom - import xpcom.components - - def getSessionObject(self, vbox): - import xpcom.components - return xpcom.components.classes["@virtualbox.org/Session;1"].createInstance() - - def getVirtualBox(self): - import xpcom.components - return xpcom.components.classes["@virtualbox.org/VirtualBox;1"].createInstance() - - def getType(self): - return 'XPCOM' - - def getRemote(self): - return False - - def getArray(self, obj, field): - return obj.__getattr__('get'+ComifyName(field))() - - def initPerThread(self): - import xpcom - xpcom._xpcom.AttachThread() - - def deinitPerThread(self): - import xpcom - xpcom._xpcom.DetachThread() - - def createListener(self, impl, arg): - d = {} - d['BaseClass'] = impl - d['arg'] = arg - str = "" - str += "import xpcom.components\n" - str += "class ListenerImpl(BaseClass):\n" - str += " _com_interfaces_ = xpcom.components.interfaces.IEventListener\n" - str += " def __init__(self): BaseClass.__init__(self, arg)\n" - str += "result = ListenerImpl()\n" - exec(str,d,d) - return d['result'] - - def waitForEvents(self, timeout): - import xpcom - return xpcom._xpcom.WaitForEvents(timeout) - - def interruptWaitEvents(self): - import xpcom - return xpcom._xpcom.InterruptWait() - - def deinit(self): - import xpcom - xpcom._xpcom.DeinitCOM() - - def queryInterface(self, obj, klazzName): - import xpcom.components - return obj.queryInterface(getattr(xpcom.components.interfaces, klazzName)) - -class PlatformWEBSERVICE: - def __init__(self, params): - sys.path.append(os.path.join(VboxSdkDir,'bindings', 'webservice', 'python', 'lib')) - #import VirtualBox_services - import VirtualBox_wrappers - from VirtualBox_wrappers import IWebsessionManager2 - - if params is not None: - self.user = params.get("user", "") - self.password = params.get("password", "") - self.url = params.get("url", "") - else: - self.user = "" - self.password = "" - self.url = None - self.vbox = None - - def getSessionObject(self, vbox): - return self.wsmgr.getSessionObject(vbox) - - def getVirtualBox(self): - return self.connect(self.url, self.user, self.password) - - def connect(self, url, user, passwd): - if self.vbox is not None: - self.disconnect() - from VirtualBox_wrappers import IWebsessionManager2 - if url is None: - url = "" - self.url = url - if user is None: - user = "" - self.user = user - if passwd is None: - passwd = "" - self.password = passwd - self.wsmgr = IWebsessionManager2(self.url) - self.vbox = self.wsmgr.logon(self.user, self.password) - if not self.vbox.handle: - raise Exception("cannot connect to '"+self.url+"' as '"+self.user+"'") - return self.vbox - - def disconnect(self): - if self.vbox is not None and self.wsmgr is not None: - self.wsmgr.logoff(self.vbox) - self.vbox = None - self.wsmgr = None - - def getType(self): - return 'WEBSERVICE' - - def getRemote(self): - return True - - def getArray(self, obj, field): - return obj.__getattr__(field) - - def initPerThread(self): - pass - - def deinitPerThread(self): - pass - - def createListener(self, impl, arg): - raise Exception("no active listeners for webservices") - - def waitForEvents(self, timeout): - # Webservices cannot do that yet - return 2; - - def interruptWaitEvents(self, timeout): - # Webservices cannot do that yet - return False; - - def deinit(self): - try: - disconnect() - except: - pass - - def queryInterface(self, obj, klazzName): - d = {} - d['obj'] = obj - str = "" - str += "from VirtualBox_wrappers import "+klazzName+"\n" - str += "result = "+klazzName+"(obj.mgr,obj.handle)\n" - # wrong, need to test if class indeed implements this interface - exec(str,d,d) - return d['result'] - -class SessionManager: - def __init__(self, mgr): - self.mgr = mgr - - def getSessionObject(self, vbox): - return self.mgr.platform.getSessionObject(vbox) - -class VirtualBoxManager: - def __init__(self, style, platparams): - if style is None: - if sys.platform == 'win32': - style = "MSCOM" - else: - style = "XPCOM" - - - exec("self.platform = Platform"+style+"(platparams)") - # for webservices, enums are symbolic - self.constants = VirtualBoxReflectionInfo(style == "WEBSERVICE") - self.type = self.platform.getType() - self.remote = self.platform.getRemote() - self.style = style - self.mgr = SessionManager(self) - - try: - self.vbox = self.platform.getVirtualBox() - except NameError as ne: - print("Installation problem: check that appropriate libs in place") - traceback.print_exc() - raise ne - except Exception as e: - print("init exception: ",e) - traceback.print_exc() - if self.remote: - self.vbox = None - else: - raise e - - def getArray(self, obj, field): - return self.platform.getArray(obj, field) - - def getVirtualBox(self): - return self.platform.getVirtualBox() - - def __del__(self): - self.deinit() - - def deinit(self): - if hasattr(self, "vbox"): - del self.vbox - self.vbox = None - if hasattr(self, "platform"): - self.platform.deinit() - self.platform = None - - def initPerThread(self): - self.platform.initPerThread() - - def openMachineSession(self, mach, permitSharing = True): - session = self.mgr.getSessionObject(self.vbox) - if permitSharing: - type = self.constants.LockType_Shared - else: - type = self.constants.LockType_Write - mach.lockMachine(session, type) - return session - - def closeMachineSession(self, session): - if session is not None: - session.unlockMachine() - - def deinitPerThread(self): - self.platform.deinitPerThread() - - def createListener(self, impl, arg = None): - return self.platform.createListener(impl, arg) - - def waitForEvents(self, timeout): - """ - Wait for events to arrive and process them. - - The timeout is in milliseconds. A negative value means waiting for - ever, while 0 does not wait at all. - - Returns 0 if events was processed. - Returns 1 if timed out or interrupted in some way. - Returns 2 on error (like not supported for web services). - - Raises an exception if the calling thread is not the main thread (the one - that initialized VirtualBoxManager) or if the time isn't an integer. - """ - return self.platform.waitForEvents(timeout) - - def interruptWaitEvents(self): - """ - Interrupt a waitForEvents call. - This is normally called from a worker thread. - - Returns True on success, False on failure. - """ - return self.platform.interruptWaitEvents() - - def getPerfCollector(self, vbox): - return PerfCollector(self, vbox) - - def getBinDir(self): - global VboxBinDir - return VboxBinDir - - def getSdkDir(self): - global VboxSdkDir - return VboxSdkDir - - def queryInterface(self, obj, klazzName): - return self.platform.queryInterface(obj, klazzName) diff --git a/gns3server/modules/virtualbox/vboxwrapper_client.py b/gns3server/modules/virtualbox/vboxwrapper_client.py deleted file mode 100644 index 911f1d50..00000000 --- a/gns3server/modules/virtualbox/vboxwrapper_client.py +++ /dev/null @@ -1,422 +0,0 @@ -# -*- coding: utf-8 -*- -# -# Copyright (C) 2014 GNS3 Technologies Inc. -# -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . - -""" -Client to VirtualBox wrapper. -""" - -import os -import time -import subprocess -import tempfile -import socket -import re - -from pkg_resources import parse_version -from ..attic import wait_socket_is_ready -from .virtualbox_error import VirtualBoxError - -import logging -log = logging.getLogger(__name__) - - -class VboxWrapperClient(object): - """ - VirtualBox Wrapper client. - - :param path: path to VirtualBox wrapper executable - :param working_dir: working directory - :param port: port - :param host: host/address - """ - - # Used to parse the VirtualBox wrapper response codes - error_re = re.compile(r"""^2[0-9]{2}-""") - success_re = re.compile(r"""^1[0-9]{2}\s{1}""") - - def __init__(self, path, working_dir, host, port=11525, timeout=30.0): - - self._path = path - self._command = [] - self._process = None - self._working_dir = working_dir - self._stderr_file = "" - self._started = False - self._host = host - self._port = port - self._timeout = timeout - self._socket = None - - @property - def started(self): - """ - Returns either VirtualBox wrapper has been started or not. - - :returns: boolean - """ - - return self._started - - @property - def path(self): - """ - Returns the path to the VirtualBox wrapper executable. - - :returns: path to VirtualBox wrapper - """ - - return self._path - - @path.setter - def path(self, path): - """ - Sets the path to the VirtualBox wrapper executable. - - :param path: path to VirtualBox wrapper - """ - - self._path = path - - @property - def port(self): - """ - Returns the port used to start the VirtualBox wrapper. - - :returns: port number (integer) - """ - - return self._port - - @port.setter - def port(self, port): - """ - Sets the port used to start the VirtualBox wrapper. - - :param port: port number (integer) - """ - - self._port = port - - @property - def host(self): - """ - Returns the host (binding) used to start the VirtualBox wrapper. - - :returns: host/address (string) - """ - - return self._host - - @host.setter - def host(self, host): - """ - Sets the host (binding) used to start the VirtualBox wrapper. - - :param host: host/address (string) - """ - - self._host = host - - def start(self): - """ - Starts the VirtualBox wrapper process. - """ - - self._command = self._build_command() - try: - log.info("starting VirtualBox wrapper: {}".format(self._command)) - with tempfile.NamedTemporaryFile(delete=False) as fd: - with open(os.devnull, "w") as null: - self._stderr_file = fd.name - log.info("VirtualBox wrapper process logging to {}".format(fd.name)) - self._process = subprocess.Popen(self._command, - stdout=null, - stderr=fd, - cwd=self._working_dir) - log.info("VirtualBox wrapper started PID={}".format(self._process.pid)) - - time.sleep(0.1) # give some time for vboxwrapper to start - if self._process.poll() is not None: - raise VirtualBoxError("Could not start VirtualBox wrapper: {}".format(self.read_stderr())) - - self.wait_for_vboxwrapper(self._host, self._port) - self.connect() - self._started = True - - version = self.send('vboxwrapper version')[0] - if parse_version(version) < parse_version("0.9.1"): - self.stop() - raise VirtualBoxError("VirtualBox wrapper version must be >= 0.9.1") - - except OSError as e: - log.error("could not start VirtualBox wrapper: {}".format(e)) - raise VirtualBoxError("Could not start VirtualBox wrapper: {}".format(e)) - - def wait_for_vboxwrapper(self, host, port): - """ - Waits for vboxwrapper to be started (accepting a socket connection) - - :param host: host/address to connect to the vboxwrapper - :param port: port to connect to the vboxwrapper - """ - - begin = time.time() - # wait for the socket for a maximum of 10 seconds. - connection_success, last_exception = wait_socket_is_ready(host, port, wait=10.0) - - if not connection_success: - raise VirtualBoxError("Couldn't connect to vboxwrapper on {}:{} :{}".format(host, port, - last_exception)) - else: - log.info("vboxwrapper server ready after {:.4f} seconds".format(time.time() - begin)) - - def stop(self): - """ - Stops the VirtualBox wrapper process. - """ - - if self.connected(): - try: - self.send("vboxwrapper stop") - except VirtualBoxError: - pass - if self._socket: - self._socket.shutdown(socket.SHUT_RDWR) - self._socket.close() - self._socket = None - - if self.is_running(): - log.info("stopping VirtualBox wrapper PID={}".format(self._process.pid)) - try: - # give some time for the VirtualBox wrapper to properly stop. - time.sleep(0.01) - self._process.terminate() - self._process.wait(1) - except subprocess.TimeoutExpired: - self._process.kill() - if self._process.poll() is None: - log.warn("VirtualBox wrapper process {} is still running".format(self._process.pid)) - - if self._stderr_file and os.access(self._stderr_file, os.W_OK): - try: - os.remove(self._stderr_file) - except OSError as e: - log.warning("could not delete temporary VirtualBox wrapper log file: {}".format(e)) - self._started = False - - def read_stderr(self): - """ - Reads the standard error output of the VirtualBox wrapper process. - Only use when the process has been stopped or has crashed. - """ - - output = "" - if self._stderr_file and os.access(self._stderr_file, os.R_OK): - try: - with open(self._stderr_file, errors="replace") as file: - output = file.read() - except OSError as e: - log.warn("could not read {}: {}".format(self._stderr_file, e)) - return output - - def is_running(self): - """ - Checks if the process is running - - :returns: True or False - """ - - if self._process and self._process.poll() is None: - return True - return False - - def _build_command(self): - """ - Command to start the VirtualBox wrapper process. - (to be passed to subprocess.Popen()) - """ - - command = [self._path] - if self._host != "0.0.0.0" and self._host != "::": - command.extend(["-l", self._host, "-p", str(self._port)]) - else: - command.extend(["-p", str(self._port)]) - return command - - def connect(self): - """ - Connects to the VirtualBox wrapper. - """ - - # connect to a local address by default - # if listening to all addresses (IPv4 or IPv6) - if self._host == "0.0.0.0": - host = "127.0.0.1" - elif self._host == "::": - host = "::1" - else: - host = self._host - - try: - self._socket = socket.create_connection((host, self._port), self._timeout) - except OSError as e: - raise VirtualBoxError("Could not connect to the VirtualBox wrapper: {}".format(e)) - - def connected(self): - """ - Returns either the client is connected to vboxwrapper or not. - - :return: boolean - """ - - if self._socket: - return True - return False - - def reset(self): - """ - Resets the VirtualBox wrapper (used to get an empty configuration). - """ - - pass - - @property - def working_dir(self): - """ - Returns current working directory - - :returns: path to the working directory - """ - - return self._working_dir - - @working_dir.setter - def working_dir(self, working_dir): - """ - Sets the working directory for the VirtualBox wrapper. - - :param working_dir: path to the working directory - """ - - # encase working_dir in quotes to protect spaces in the path - #self.send("hypervisor working_dir {}".format('"' + working_dir + '"')) - self._working_dir = working_dir - log.debug("working directory set to {}".format(self._working_dir)) - - @property - def socket(self): - """ - Returns the current socket used to communicate with the VirtualBox wrapper. - - :returns: socket instance - """ - - assert self._socket - return self._socket - - def get_vm_list(self): - """ - Returns the list of all VirtualBox VMs. - - :returns: list of VM names - """ - - return self.send('vbox vm_list') - - def send(self, command): - """ - Sends commands to the VirtualBox wrapper. - - :param command: a VirtualBox wrapper command - - :returns: results as a list - """ - - # VirtualBox wrapper responses are of the form: - # 1xx yyyyyy\r\n - # 1xx yyyyyy\r\n - # ... - # 100-yyyy\r\n - # or - # 2xx-yyyy\r\n - # - # Where 1xx is a code from 100-199 for a success or 200-299 for an error - # The result might be multiple lines and might be less than the buffer size - # but still have more data. The only thing we know for sure is the last line - # will begin with '100-' or a '2xx-' and end with '\r\n' - - if not self._socket: - raise VirtualBoxError("Not connected") - - try: - command = command.strip() + '\n' - log.debug("sending {}".format(command)) - self.socket.sendall(command.encode('utf-8')) - except OSError as e: - self._socket = None - raise VirtualBoxError("Lost communication with {host}:{port} :{error}" - .format(host=self._host, port=self._port, error=e)) - - # Now retrieve the result - data = [] - buf = '' - while True: - try: - chunk = self.socket.recv(1024) - buf += chunk.decode("utf-8") - except OSError as e: - self._socket = None - raise VirtualBoxError("Communication timed out with {host}:{port} :{error}" - .format(host=self._host, port=self._port, error=e)) - - - # If the buffer doesn't end in '\n' then we can't be done - try: - if buf[-1] != '\n': - continue - except IndexError: - self._socket = None - raise VirtualBoxError("Could not communicate with {host}:{port}" - .format(host=self._host, port=self._port)) - - data += buf.split('\r\n') - if data[-1] == '': - data.pop() - buf = '' - - if len(data) == 0: - raise VirtualBoxError("no data returned from {host}:{port}" - .format(host=self._host, port=self._port)) - - # Does it contain an error code? - if self.error_re.search(data[-1]): - raise VirtualBoxError(data[-1][4:]) - - # Or does the last line begin with '100-'? Then we are done! - if data[-1][:4] == '100-': - data[-1] = data[-1][4:] - if data[-1] == 'OK': - data.pop() - break - - # Remove success responses codes - for index in range(len(data)): - if self.success_re.search(data[index]): - data[index] = data[index][4:] - - log.debug("returned result {}".format(data)) - return data diff --git a/gns3server/modules/virtualbox/virtualbox_controller.py b/gns3server/modules/virtualbox/virtualbox_controller.py deleted file mode 100644 index f4f02aff..00000000 --- a/gns3server/modules/virtualbox/virtualbox_controller.py +++ /dev/null @@ -1,555 +0,0 @@ -# -*- coding: utf-8 -*- -# -# Copyright (C) 2014 GNS3 Technologies Inc. -# -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . - -""" -Controls VirtualBox using the VBox API. -""" - -import sys -import os -import tempfile -import re -import time -import socket -import subprocess - -if sys.platform.startswith('win'): - import msvcrt - import win32file - -from .virtualbox_error import VirtualBoxError -from .pipe_proxy import PipeProxy - -import logging -log = logging.getLogger(__name__) - - -class VirtualBoxController(object): - - def __init__(self, vmname, vboxmanager, host): - - self._host = host - self._machine = None - self._session = None - self._vboxmanager = vboxmanager - self._maximum_adapters = 0 - self._serial_pipe_thread = None - self._serial_pipe = None - - self._vmname = vmname - self._console = 0 - self._adapters = [] - self._headless = False - self._enable_console = False - self._adapter_type = "Automatic" - - try: - self._machine = self._vboxmanager.vbox.findMachine(self._vmname) - except Exception as e: - raise VirtualBoxError("VirtualBox error: {}".format(e)) - - # The maximum support network cards depends on the Chipset (PIIX3 or ICH9) - self._maximum_adapters = self._vboxmanager.vbox.systemProperties.getMaxNetworkAdapters(self._machine.chipsetType) - - @property - def vmname(self): - - return self._vmname - - @vmname.setter - def vmname(self, new_vmname): - - self._vmname = new_vmname - try: - self._machine = self._vboxmanager.vbox.findMachine(new_vmname) - except Exception as e: - raise VirtualBoxError("VirtualBox error: {}".format(e)) - - # The maximum support network cards depends on the Chipset (PIIX3 or ICH9) - self._maximum_adapters = self._vboxmanager.vbox.systemProperties.getMaxNetworkAdapters(self._machine.chipsetType) - - @property - def console(self): - - return self._console - - @console.setter - def console(self, console): - - self._console = console - - @property - def headless(self): - - return self._headless - - @headless.setter - def headless(self, headless): - - self._headless = headless - - @property - def enable_console(self): - - return self._enable_console - - @enable_console.setter - def enable_console(self, enable_console): - - self._enable_console = enable_console - - @property - def adapters(self): - - return self._adapters - - @adapters.setter - def adapters(self, adapters): - - self._adapters = adapters - - @property - def adapter_type(self): - - return self._adapter_type - - @adapter_type.setter - def adapter_type(self, adapter_type): - - self._adapter_type = adapter_type - - def start(self): - - if len(self._adapters) > self._maximum_adapters: - raise VirtualBoxError("Number of adapters above the maximum supported of {}".format(self._maximum_adapters)) - - if self._machine.state == self._vboxmanager.constants.MachineState_Paused: - self.resume() - return - - self._get_session() - self._set_network_options() - self._set_console_options() - - progress = self._launch_vm_process() - log.info("VM is starting with {}% completed".format(progress.percent)) - if progress.percent != 100: - # This will happen if you attempt to start VirtualBox with unloaded "vboxdrv" module. - # or have too little RAM or damaged vHDD, or connected to non-existent network. - # We must unlock machine, otherwise it locks the VirtualBox Manager GUI. (on Linux hosts) - self._unlock_machine() - raise VirtualBoxError("Unable to start the VM (failed at {}%)".format(progress.percent)) - - try: - self._machine.setGuestPropertyValue("NameInGNS3", self._name) - except Exception: - pass - - if self._enable_console: - # starts the Telnet to pipe thread - pipe_name = self._get_pipe_name() - if sys.platform.startswith('win'): - try: - self._serial_pipe = open(pipe_name, "a+b") - except OSError as e: - raise VirtualBoxError("Could not open the pipe {}: {}".format(pipe_name, e)) - self._serial_pipe_thread = PipeProxy(self._vmname, msvcrt.get_osfhandle(self._serial_pipe.fileno()), self._host, self._console) - #self._serial_pipe_thread.setDaemon(True) - self._serial_pipe_thread.start() - else: - try: - self._serial_pipe = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) - self._serial_pipe.connect(pipe_name) - except OSError as e: - raise VirtualBoxError("Could not connect to the pipe {}: {}".format(pipe_name, e)) - self._serial_pipe_thread = PipeProxy(self._vmname, self._serial_pipe, self._host, self._console) - #self._serial_pipe_thread.setDaemon(True) - self._serial_pipe_thread.start() - - def stop(self): - - if self._serial_pipe_thread: - self._serial_pipe_thread.stop() - self._serial_pipe_thread.join(1) - if self._serial_pipe_thread.isAlive(): - log.warn("Serial pire thread is still alive!") - self._serial_pipe_thread = None - - if self._serial_pipe: - if sys.platform.startswith('win'): - win32file.CloseHandle(msvcrt.get_osfhandle(self._serial_pipe.fileno())) - else: - self._serial_pipe.close() - self._serial_pipe = None - - if self._machine.state >= self._vboxmanager.constants.MachineState_FirstOnline and \ - self._machine.state <= self._vboxmanager.constants.MachineState_LastOnline: - try: - if sys.platform.startswith('win') and "VBOX_INSTALL_PATH" in os.environ: - # work around VirtualBox bug #9239 - vboxmanage_path = os.path.join(os.environ["VBOX_INSTALL_PATH"], "VBoxManage.exe") - command = '"{}" controlvm "{}" poweroff'.format(vboxmanage_path, self._vmname) - subprocess.call(command, timeout=3) - else: - progress = self._session.console.powerDown() - # wait for VM to actually go down - progress.waitForCompletion(3000) - log.info("VM is stopping with {}% completed".format(self.vmname, progress.percent)) - - self._lock_machine() - - for adapter_id in range(0, len(self._adapters)): - if self._adapters[adapter_id] is None: - continue - self._disable_adapter(adapter_id, disable=True) - serial_port = self._session.machine.getSerialPort(0) - serial_port.enabled = False - self._session.machine.saveSettings() - self._unlock_machine() - except Exception as e: - # Do not crash "vboxwrapper", if stopping VM fails. - # But return True anyway, so VM state in GNS3 can become "stopped" - # This can happen, if user manually kills VBox VM. - log.warn("could not stop VM for {}: {}".format(self._vmname, e)) - return - - def suspend(self): - - try: - self._session.console.pause() - except Exception as e: - raise VirtualBoxError("VirtualBox error: {}".format(e)) - - def reload(self): - - try: - self._session.console.reset() - except Exception as e: - raise VirtualBoxError("VirtualBox error: {}".format(e)) - - def resume(self): - - try: - self._session.console.resume() - except Exception as e: - raise VirtualBoxError("VirtualBox error: {}".format(e)) - - def _get_session(self): - - log.debug("getting session for {}".format(self._vmname)) - try: - self._session = self._vboxmanager.mgr.getSessionObject(self._vboxmanager.vbox) - except Exception as e: - # fails on heavily loaded hosts... - raise VirtualBoxError("VirtualBox error: {}".format(e)) - - def _set_network_options(self): - - log.debug("setting network options for {}".format(self._vmname)) - - self._lock_machine() - - first_adapter_type = self._vboxmanager.constants.NetworkAdapterType_I82540EM - try: - first_adapter = self._session.machine.getNetworkAdapter(0) - first_adapter_type = first_adapter.adapterType - except Exception as e: - pass - #raise VirtualBoxError("VirtualBox error: {}".format(e)) - - for adapter_id in range(0, len(self._adapters)): - - try: - # VirtualBox starts counting from 0 - adapter = self._session.machine.getNetworkAdapter(adapter_id) - if self._adapters[adapter_id] is None: - # force enable to avoid any discrepancy in the interface numbering inside the VM - # e.g. Ethernet2 in GNS3 becoming eth0 inside the VM when using a start index of 2. - adapter.enabled = True - continue - - vbox_adapter_type = adapter.adapterType - if self._adapter_type == "PCnet-PCI II (Am79C970A)": - vbox_adapter_type = self._vboxmanager.constants.NetworkAdapterType_Am79C970A - if self._adapter_type == "PCNet-FAST III (Am79C973)": - vbox_adapter_type = self._vboxmanager.constants.NetworkAdapterType_Am79C973 - if self._adapter_type == "Intel PRO/1000 MT Desktop (82540EM)": - vbox_adapter_type = self._vboxmanager.constants.NetworkAdapterType_I82540EM - if self._adapter_type == "Intel PRO/1000 T Server (82543GC)": - vbox_adapter_type = self._vboxmanager.constants.NetworkAdapterType_I82543GC - if self._adapter_type == "Intel PRO/1000 MT Server (82545EM)": - vbox_adapter_type = self._vboxmanager.constants.NetworkAdapterType_I82545EM - if self._adapter_type == "Paravirtualized Network (virtio-net)": - vbox_adapter_type = self._vboxmanager.constants.NetworkAdapterType_Virtio - if self._adapter_type == "Automatic": # "Auto-guess, based on first NIC" - vbox_adapter_type = first_adapter_type - - adapter.adapterType = vbox_adapter_type - - except Exception as e: - raise VirtualBoxError("VirtualBox error: {}".format(e)) - - nio = self._adapters[adapter_id].get_nio(0) - if nio: - log.debug("setting UDP params on adapter {}".format(adapter_id)) - try: - adapter.enabled = True - adapter.cableConnected = True - adapter.traceEnabled = False - # Temporary hack around VBox-UDP patch limitation: inability to use DNS - if nio.rhost == 'localhost': - rhost = '127.0.0.1' - else: - rhost = nio.rhost - adapter.attachmentType = self._vboxmanager.constants.NetworkAttachmentType_Generic - adapter.genericDriver = "UDPTunnel" - adapter.setProperty("sport", str(nio.lport)) - adapter.setProperty("dest", rhost) - adapter.setProperty("dport", str(nio.rport)) - except Exception as e: - # usually due to COM Error: "The object is not ready" - raise VirtualBoxError("VirtualBox error: {}".format(e)) - - if nio.capturing: - self._enable_capture(adapter, nio.pcap_output_file) - - else: - # shutting down unused adapters... - try: - adapter.enabled = True - adapter.attachmentType = self._vboxmanager.constants.NetworkAttachmentType_Null - adapter.cableConnected = False - except Exception as e: - raise VirtualBoxError("VirtualBox error: {}".format(e)) - - for adapter_id in range(len(self._adapters), self._maximum_adapters): - log.debug("disabling remaining adapter {}".format(adapter_id)) - self._disable_adapter(adapter_id) - - try: - self._session.machine.saveSettings() - except Exception as e: - raise VirtualBoxError("VirtualBox error: {}".format(e)) - - self._unlock_machine() - - def _disable_adapter(self, adapter_id, disable=True): - - log.debug("disabling network adapter for {}".format(self._vmname)) - # this command is retried several times, because it fails more often... - retries = 6 - last_exception = None - for retry in range(retries): - if retry == (retries - 1): - raise VirtualBoxError("Could not disable network adapter after 4 retries: {}".format(last_exception)) - try: - adapter = self._session.machine.getNetworkAdapter(adapter_id) - adapter.traceEnabled = False - adapter.attachmentType = self._vboxmanager.constants.NetworkAttachmentType_Null - if disable: - adapter.enabled = False - break - except Exception as e: - # usually due to COM Error: "The object is not ready" - log.warn("cannot disable network adapter for {}, retrying {}: {}".format(self._vmname, retry + 1, e)) - last_exception = e - time.sleep(1) - continue - - def _enable_capture(self, adapter, output_file): - - log.debug("enabling capture for {}".format(self._vmname)) - # this command is retried several times, because it fails more often... - retries = 4 - last_exception = None - for retry in range(retries): - if retry == (retries - 1): - raise VirtualBoxError("Could not enable packet capture after 4 retries: {}".format(last_exception)) - try: - adapter.traceEnabled = True - adapter.traceFile = output_file - break - except Exception as e: - log.warn("cannot enable packet capture for {}, retrying {}: {}".format(self._vmname, retry + 1, e)) - last_exception = e - time.sleep(0.75) - continue - - def create_udp(self, adapter_id, sport, daddr, dport): - - if self._machine.state >= self._vboxmanager.constants.MachineState_FirstOnline and \ - self._machine.state <= self._vboxmanager.constants.MachineState_LastOnline: - # the machine is being executed - retries = 4 - last_exception = None - for retry in range(retries): - if retry == (retries - 1): - raise VirtualBoxError("Could not create an UDP tunnel after 4 retries :{}".format(last_exception)) - try: - adapter = self._session.machine.getNetworkAdapter(adapter_id) - adapter.cableConnected = True - adapter.attachmentType = self._vboxmanager.constants.NetworkAttachmentType_Null - self._session.machine.saveSettings() - adapter.attachmentType = self._vboxmanager.constants.NetworkAttachmentType_Generic - adapter.genericDriver = "UDPTunnel" - adapter.setProperty("sport", str(sport)) - adapter.setProperty("dest", daddr) - adapter.setProperty("dport", str(dport)) - self._session.machine.saveSettings() - break - except Exception as e: - # usually due to COM Error: "The object is not ready" - log.warn("cannot create UDP tunnel for {}: {}".format(self._vmname, e)) - last_exception = e - time.sleep(0.75) - continue - - def delete_udp(self, adapter_id): - - if self._machine.state >= self._vboxmanager.constants.MachineState_FirstOnline and \ - self._machine.state <= self._vboxmanager.constants.MachineState_LastOnline: - # the machine is being executed - retries = 4 - last_exception = None - for retry in range(retries): - if retry == (retries - 1): - raise VirtualBoxError("Could not delete an UDP tunnel after 4 retries :{}".format(last_exception)) - try: - adapter = self._session.machine.getNetworkAdapter(adapter_id) - adapter.attachmentType = self._vboxmanager.constants.NetworkAttachmentType_Null - adapter.cableConnected = False - self._session.machine.saveSettings() - break - except Exception as e: - # usually due to COM Error: "The object is not ready" - log.debug("cannot delete UDP tunnel for {}: {}".format(self._vmname, e)) - last_exception = e - time.sleep(0.75) - continue - - def _get_pipe_name(self): - - p = re.compile('\s+', re.UNICODE) - pipe_name = p.sub("_", self._vmname) - if sys.platform.startswith('win'): - pipe_name = r"\\.\pipe\VBOX\{}".format(pipe_name) - else: - pipe_name = os.path.join(tempfile.gettempdir(), "pipe_{}".format(pipe_name)) - return pipe_name - - def _set_console_options(self): - """ - # Example to manually set serial parameters using Python - - from vboxapi import VirtualBoxManager - mgr = VirtualBoxManager(None, None) - mach = mgr.vbox.findMachine("My VM") - session = mgr.mgr.getSessionObject(mgr.vbox) - mach.lockMachine(session, 1) - mach2=session.machine - serial_port = mach2.getSerialPort(0) - serial_port.enabled = True - serial_port.path = "/tmp/test_pipe" - serial_port.hostMode = 1 - serial_port.server = True - session.unlockMachine() - """ - - log.info("setting console options for {}".format(self._vmname)) - - self._lock_machine() - pipe_name = self._get_pipe_name() - - try: - serial_port = self._session.machine.getSerialPort(0) - serial_port.enabled = True - serial_port.path = pipe_name - serial_port.hostMode = 1 - serial_port.server = True - self._session.machine.saveSettings() - except Exception as e: - raise VirtualBoxError("VirtualBox error: {}".format(e)) - - self._unlock_machine() - - def _launch_vm_process(self): - - log.debug("launching VM {}".format(self._vmname)) - # this command is retried several times, because it fails more often... - retries = 4 - last_exception = None - for retry in range(retries): - if retry == (retries - 1): - raise VirtualBoxError("Could not launch the VM after 4 retries: {}".format(last_exception)) - try: - if self._headless: - mode = "headless" - else: - mode = "gui" - log.info("starting {} in {} mode".format(self._vmname, mode)) - progress = self._machine.launchVMProcess(self._session, mode, "") - break - except Exception as e: - # This will usually happen if you try to start the same VM twice, - # but may happen on loaded hosts too... - log.warn("cannot launch VM {}, retrying {}: {}".format(self._vmname, retry + 1, e)) - last_exception = e - time.sleep(0.6) - continue - - try: - progress.waitForCompletion(-1) - except Exception as e: - raise VirtualBoxError("VirtualBox error: {}".format(e)) - - return progress - - def _lock_machine(self): - - log.debug("locking machine for {}".format(self._vmname)) - # this command is retried several times, because it fails more often... - retries = 4 - last_exception = None - for retry in range(retries): - if retry == (retries - 1): - raise VirtualBoxError("Could not lock the machine after 4 retries: {}".format(last_exception)) - try: - self._machine.lockMachine(self._session, 1) - break - except Exception as e: - log.warn("cannot lock the machine for {}, retrying {}: {}".format(self._vmname, retry + 1, e)) - last_exception = e - time.sleep(1) - continue - - def _unlock_machine(self): - - log.debug("unlocking machine for {}".format(self._vmname)) - # this command is retried several times, because it fails more often... - retries = 4 - last_exception = None - for retry in range(retries): - if retry == (retries - 1): - raise VirtualBoxError("Could not unlock the machine after 4 retries: {}".format(last_exception)) - try: - self._session.unlockMachine() - break - except Exception as e: - log.warn("cannot unlock the machine for {}, retrying {}: {}".format(self._vmname, retry + 1, e)) - time.sleep(1) - last_exception = e - continue diff --git a/gns3server/modules/virtualbox/virtualbox_vm.py b/gns3server/modules/virtualbox/virtualbox_vm.py index dee20427..5a00eb1f 100644 --- a/gns3server/modules/virtualbox/virtualbox_vm.py +++ b/gns3server/modules/virtualbox/virtualbox_vm.py @@ -19,13 +19,24 @@ VirtualBox VM instance. """ +import sys +import shlex +import re import os +import subprocess +import tempfile import shutil +import socket +import time from .virtualbox_error import VirtualBoxError -from .virtualbox_controller import VirtualBoxController from .adapters.ethernet_adapter import EthernetAdapter from ..attic import find_unused_port +from .pipe_proxy import PipeProxy + +if sys.platform.startswith('win'): + import msvcrt + import win32file import logging log = logging.getLogger(__name__) @@ -35,8 +46,7 @@ class VirtualBoxVM(object): """ VirtualBox VM implementation. - :param vboxwrapper client: VboxWrapperClient instance - :param vboxmanager: VirtualBox manager from the VirtualBox API + :param vboxmanage_path: path to the VBoxManage tool :param name: name of this VirtualBox VM :param vmname: name of this VirtualBox VM in VirtualBox itself :param working_dir: path to a working directory @@ -51,8 +61,7 @@ class VirtualBoxVM(object): _allocated_console_ports = [] def __init__(self, - vboxwrapper, - vboxmanager, + vboxmanage_path, name, vmname, working_dir, @@ -82,11 +91,14 @@ class VirtualBoxVM(object): self._working_dir = None self._host = host self._command = [] - self._vboxwrapper = vboxwrapper + self._vboxmanage_path = vboxmanage_path self._started = False self._console_start_port_range = console_start_port_range self._console_end_port_range = console_end_port_range + self._serial_pipe_thread = None + self._serial_pipe = None + # VirtualBox settings self._console = console self._ethernet_adapters = [] @@ -118,13 +130,14 @@ class VirtualBoxVM(object): raise VirtualBoxError("Console port {} is already used by another VirtualBox VM".format(console)) self._allocated_console_ports.append(self._console) - if self._vboxwrapper: - self._vboxwrapper.send('vbox create vbox "{}"'.format(self._name)) - self._vboxwrapper.send('vbox setattr "{}" image "{}"'.format(self._name, vmname)) - self._vboxwrapper.send('vbox setattr "{}" console {}'.format(self._name, self._console)) - else: - self._vboxcontroller = VirtualBoxController(self._vmname, vboxmanager, self._host) - self._vboxcontroller.console = self._console + self._system_properties = {} + properties = self._execute("list", ["systemproperties"]) + for prop in properties: + try: + name, value = prop.split(':', 1) + except ValueError: + continue + self._system_properties[name.strip()] = value.strip() self.adapters = 2 # creates 2 adapters by default log.info("VirtualBox VM {name} [id={id}] has been created".format(name=self._name, @@ -189,8 +202,6 @@ class VirtualBoxVM(object): id=self._id, new_name=new_name)) - if self._vboxwrapper: - self._vboxwrapper.send('vbox rename "{}" "{}"'.format(self._name, new_name)) self._name = new_name @property @@ -248,11 +259,6 @@ class VirtualBoxVM(object): self._console = console self._allocated_console_ports.append(self._console) - if self._vboxwrapper: - self._vboxwrapper.send('vbox setattr "{}" console {}'.format(self._name, self._console)) - else: - self._vboxcontroller.console = console - log.info("VirtualBox VM {name} [id={id}]: console port set to {port}".format(name=self._name, id=self._id, port=console)) @@ -269,9 +275,6 @@ class VirtualBoxVM(object): if self.console and self.console in self._allocated_console_ports: self._allocated_console_ports.remove(self.console) - if self._vboxwrapper: - self._vboxwrapper.send('vbox delete "{}"'.format(self._name)) - log.info("VirtualBox VM {name} [id={id}] has been deleted".format(name=self._name, id=self._id)) @@ -287,9 +290,6 @@ class VirtualBoxVM(object): if self.console: self._allocated_console_ports.remove(self.console) - if self._vboxwrapper: - self._vboxwrapper.send('vbox delete "{}"'.format(self._name)) - try: shutil.rmtree(self._working_dir) except OSError as e: @@ -320,16 +320,8 @@ class VirtualBoxVM(object): """ if headless: - if self._vboxwrapper: - self._vboxwrapper.send('vbox setattr "{}" headless_mode True'.format(self._name)) - else: - self._vboxcontroller.headless = True log.info("VirtualBox VM {name} [id={id}] has enabled the headless mode".format(name=self._name, id=self._id)) else: - if self._vboxwrapper: - self._vboxwrapper.send('vbox setattr "{}" headless_mode False'.format(self._name)) - else: - self._vboxcontroller.headless = False log.info("VirtualBox VM {name} [id={id}] has disabled the headless mode".format(name=self._name, id=self._id)) self._headless = headless @@ -352,16 +344,8 @@ class VirtualBoxVM(object): """ if enable_console: - if self._vboxwrapper: - self._vboxwrapper.send('vbox setattr "{}" enable_console True'.format(self._name)) - else: - self._vboxcontroller.enable_console = True log.info("VirtualBox VM {name} [id={id}] has enabled the console".format(name=self._name, id=self._id)) else: - if self._vboxwrapper: - self._vboxwrapper.send('vbox setattr "{}" enable_console False'.format(self._name)) - else: - self._vboxcontroller.enable_console = False log.info("VirtualBox VM {name} [id={id}] has disabled the console".format(name=self._name, id=self._id)) self._enable_console = enable_console @@ -383,11 +367,6 @@ class VirtualBoxVM(object): :param vmname: VirtualBox VM name """ - if self._vboxwrapper: - self._vboxwrapper.send('vbox setattr "{}" image "{}"'.format(self._name, vmname)) - else: - self._vboxcontroller.vmname = vmname - log.info("VirtualBox VM {name} [id={id}] has set the VM name to {vmname}".format(name=self._name, id=self._id, vmname=vmname)) self._vmname = vmname @@ -416,11 +395,6 @@ class VirtualBoxVM(object): continue self._ethernet_adapters.append(EthernetAdapter()) - if self._vboxwrapper: - self._vboxwrapper.send('vbox setattr "{}" nics {}'.format(self._name, adapters)) - else: - self._vboxcontroller.adapters = self._ethernet_adapters - log.info("VirtualBox VM {name} [id={id}]: number of Ethernet adapters changed to {adapters}".format(name=self._name, id=self._id, adapters=adapters)) @@ -443,9 +417,6 @@ class VirtualBoxVM(object): :param adapter_start_index: index """ - if self._vboxwrapper: - self._vboxwrapper.send('vbox setattr "{}" nic_start_index {}'.format(self._name, adapter_start_index)) - self._adapter_start_index = adapter_start_index self.adapters = self.adapters # this forces to recreate the adapter list with the correct index log.info("VirtualBox VM {name} [id={id}]: adapter start index changed to {index}".format(name=self._name, @@ -472,68 +443,327 @@ class VirtualBoxVM(object): self._adapter_type = adapter_type - if self._vboxwrapper: - self._vboxwrapper.send('vbox setattr "{}" netcard "{}"'.format(self._name, adapter_type)) - else: - self._vboxcontroller.adapter_type = adapter_type - log.info("VirtualBox VM {name} [id={id}]: adapter type changed to {adapter_type}".format(name=self._name, id=self._id, adapter_type=adapter_type)) + def _execute(self, subcommand, args, timeout=30): + """ + Executes a command with VBoxManage. + + :param subcommand: vboxmanage subcommand (e.g. modifyvm, controlvm etc.) + :param args: arguments for the subcommand. + :param timeout: how long to wait for vboxmanage + + :returns: result (list) + """ + + command = [self._vboxmanage_path, "--nologo", subcommand] + command.extend(args) + try: + result = subprocess.check_output(command, stderr=subprocess.STDOUT, universal_newlines=True, timeout=timeout) + except subprocess.CalledProcessError as e: + if e.output: + # only the first line of the output is useful + virtualbox_error = e.output.splitlines()[0] + raise VirtualBoxError("{}".format(e)) + except subprocess.TimeoutExpired: + raise VirtualBoxError("VBoxManage has timed out") + return result.splitlines() + + def _get_vm_info(self): + """ + Returns this VM info. + + :returns: dict of info + """ + + vm_info = {} + results = self._execute("showvminfo", [self._vmname]) + for info in results: + try: + name, value = info.split(':', 1) + except ValueError: + continue + vm_info[name.strip()] = value.strip() + return vm_info + + def _get_vm_state(self): + """ + Returns this VM state (e.g. running, paused etc.) + + :returns: state (string) + """ + + vm_info = self._get_vm_info() + state = vm_info["State"].rsplit('(', 1)[0] + return state.lower().strip() + + def _get_maximum_supported_adapters(self): + """ + Returns the maximum adapters supported by this VM. + + :returns: maximum number of supported adapters (int) + """ + + # check the maximum number of adapters supported by the VM + vm_info = self._get_vm_info() + chipset = vm_info["Chipset"] + maximum_adapters = 8 + if chipset == "ich9": + maximum_adapters = int(self._system_properties["Maximum ICH9 Network Adapter count"]) + return maximum_adapters + + def _get_pipe_name(self): + """ + Returns the pipe name to create a serial connection. + + :returns: pipe path (string) + """ + + p = re.compile('\s+', re.UNICODE) + pipe_name = p.sub("_", self._vmname) + if sys.platform.startswith('win'): + pipe_name = r"\\.\pipe\VBOX\{}".format(pipe_name) + else: + pipe_name = os.path.join(tempfile.gettempdir(), "pipe_{}".format(pipe_name)) + return pipe_name + + def _set_serial_console(self): + """ + Configures the first serial port to allow a serial console connection. + """ + + # activate the first serial port + self._modify_vm("--uart1 0x3F8 4") + + # set server mode with a pipe on the first serial port + pipe_name = self._get_pipe_name() + args = [self._vmname, "--uartmode1", "server", pipe_name] + self._execute("modifyvm", args) + + def _modify_vm(self, params): + """ + Change setting in this VM when not running. + + :param params: params to use with sub-command modifyvm + """ + + args = shlex.split(params) + self._execute("modifyvm", [self._vmname] + args) + + def _control_vm(self, params): + """ + Change setting in this VM when running. + + :param params: params to use with sub-command controlvm + + :returns: result of the command. + """ + + args = shlex.split(params) + return self._execute("controlvm", [self._vmname] + args) + + def _get_nic_attachements(self, maximum_adapters): + """ + Returns NIC attachements. + + :param maximum_adapters: maximum number of supported adapters + :returns: list of adapters with their Attachment setting (NAT, bridged etc.) + """ + + nics = [] + vm_info = self._get_vm_info() + for adapter_id in range(0, maximum_adapters): + entry = "NIC {}".format(adapter_id + 1) + if entry in vm_info: + value = vm_info[entry] + match = re.search("Attachment: (\w+)[\s,]+", value) + if match: + nics.append(match.group(1)) + else: + nics.append(None) + return nics + + def _set_network_options(self, maximum_adapters): + """ + Configures network options. + + :param maximum_adapters: maximum number of supported adapters + """ + + nic_attachements = self._get_nic_attachements(maximum_adapters) + for adapter_id in range(0, len(self._ethernet_adapters)): + if self._ethernet_adapters[adapter_id] is None: + # force enable to avoid any discrepancy in the interface numbering inside the VM + # e.g. Ethernet2 in GNS3 becoming eth0 inside the VM when using a start index of 2. + attachement = nic_attachements[adapter_id] + if attachement: + self._modify_vm("--nic{} {}".format(adapter_id + 1, attachement.lower())) + continue + + vbox_adapter_type = "82540EM" + if self._adapter_type == "PCnet-PCI II (Am79C970A)": + vbox_adapter_type = "Am79C970A" + if self._adapter_type == "PCNet-FAST III (Am79C973)": + vbox_adapter_type = "Am79C973" + if self._adapter_type == "Intel PRO/1000 MT Desktop (82540EM)": + vbox_adapter_type = "82540EM" + if self._adapter_type == "Intel PRO/1000 T Server (82543GC)": + vbox_adapter_type = "82543GC" + if self._adapter_type == "Intel PRO/1000 MT Server (82545EM)": + vbox_adapter_type = "82545EM" + if self._adapter_type == "Paravirtualized Network (virtio-net)": + vbox_adapter_type = "virtio" + + args = [self._vmname, "--nictype{}".format(adapter_id + 1), vbox_adapter_type] + self._execute("modifyvm", args) + + nio = self._ethernet_adapters[adapter_id].get_nio(0) + if nio: + log.debug("setting UDP params on adapter {}".format(adapter_id)) + try: + + self._modify_vm("--nic{} generic".format(adapter_id + 1)) + self._modify_vm("--nicgenericdrv{} UDPTunnel".format(adapter_id + 1)) + self._modify_vm("--nicproperty{} sport={}".format(adapter_id + 1, nio.lport)) + self._modify_vm("--nicproperty{} dest={}".format(adapter_id + 1, nio.rhost)) + self._modify_vm("--nicproperty{} dport={}".format(adapter_id + 1, nio.rport)) + self._modify_vm("--cableconnected{} on".format(adapter_id + 1)) + + except Exception as e: + raise VirtualBoxError("VirtualBox error: {}".format(e)) + + if nio.capturing: + self._modify_vm("--nictrace{} on".format(adapter_id + 1)) + self._modify_vm("--nictracefile{} {}".format(adapter_id + 1, nio.pcap_output_file)) + else: + self._modify_vm("--nictrace{} off".format(adapter_id + 1)) + else: + # shutting down unused adapters... + try: + self._modify_vm("--nic{} null".format(adapter_id + 1)) + except Exception as e: + raise VirtualBoxError("VirtualBox error: {}".format(e)) + + for adapter_id in range(len(self._ethernet_adapters), maximum_adapters): + log.debug("disabling remaining adapter {}".format(adapter_id)) + self._modify_vm("--nic{} null".format(adapter_id + 1)) + def start(self): """ Starts this VirtualBox VM. """ - if self._vboxwrapper: - self._vboxwrapper.send('vbox start "{}"'.format(self._name)) - else: - self._vboxcontroller.start() + # resume the VM if it is paused + vm_state = self._get_vm_state() + if vm_state == "paused": + self.resume() + return + + # VM must be powered off and in saved state to start it + if vm_state != "powered off" and vm_state != "saved": + raise VirtualBoxError("VirtualBox VM not powered off or saved") + + # check for the maximum adapters supported by the VM + maximum_adapters = self._get_maximum_supported_adapters() + if len(self._ethernet_adapters) > maximum_adapters: + raise VirtualBoxError("Number of adapters above the maximum supported of {}".format(maximum_adapters)) + + self._set_network_options(maximum_adapters) + self._set_serial_console() + + args = [self._vmname] + if self._headless: + args.extend(["--type", "headless"]) + result = self._execute("startvm", args) + log.debug("started VirtualBox VM: {}".format(result)) + + if self._enable_console: + # starts the Telnet to pipe thread + pipe_name = self._get_pipe_name() + if sys.platform.startswith('win'): + try: + self._serial_pipe = open(pipe_name, "a+b") + except OSError as e: + raise VirtualBoxError("Could not open the pipe {}: {}".format(pipe_name, e)) + self._serial_pipe_thread = PipeProxy(self._vmname, msvcrt.get_osfhandle(self._serial_pipe.fileno()), self._host, self._console) + #self._serial_pipe_thread.setDaemon(True) + self._serial_pipe_thread.start() + else: + try: + self._serial_pipe = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) + self._serial_pipe.connect(pipe_name) + except OSError as e: + raise VirtualBoxError("Could not connect to the pipe {}: {}".format(pipe_name, e)) + self._serial_pipe_thread = PipeProxy(self._vmname, self._serial_pipe, self._host, self._console) + #self._serial_pipe_thread.setDaemon(True) + self._serial_pipe_thread.start() def stop(self): """ Stops this VirtualBox VM. """ - if self._vboxwrapper: + if self._serial_pipe_thread: + self._serial_pipe_thread.stop() + self._serial_pipe_thread.join(1) + if self._serial_pipe_thread.isAlive(): + log.warn("Serial pire thread is still alive!") + self._serial_pipe_thread = None + + if self._serial_pipe: + if sys.platform.startswith('win'): + win32file.CloseHandle(msvcrt.get_osfhandle(self._serial_pipe.fileno())) + else: + self._serial_pipe.close() + self._serial_pipe = None + + vm_state = self._get_vm_state() + if vm_state == "running" or vm_state == "paused" or vm_state == "stuck": + # power off the VM + result = self._control_vm("poweroff") + log.debug("VirtualBox VM has been stopped: {}".format(result)) + + time.sleep(0.5) # give some time for VirtualBox to unlock the VM + # deactivate the first serial port try: - self._vboxwrapper.send('vbox stop "{}"'.format(self._name)) - except VirtualBoxError: - # probably lost the connection - return - else: - self._vboxcontroller.stop() + self._modify_vm("--uart1 off") + except VirtualBoxError as e: + log.warn("Could not deactivate the first serial port: {}".format(e)) + + for adapter_id in range(0, len(self._ethernet_adapters)): + if self._ethernet_adapters[adapter_id] is None: + continue + self._modify_vm("--nic{} null".format(adapter_id + 1)) def suspend(self): """ Suspends this VirtualBox VM. """ - if self._vboxwrapper: - self._vboxwrapper.send('vbox suspend "{}"'.format(self._name)) + vm_state = self._get_vm_state() + if vm_state == "running": + result = self._control_vm("pause") + log.debug("VirtualBox VM has been suspended: {}".format(result)) else: - self._vboxcontroller.suspend() + log.info("VirtualBox VM is not running to be suspended, current state is {}".format(vm_state)) - def reload(self): + def resume(self): """ - Reloads this VirtualBox VM. + Resumes this VirtualBox VM. """ - if self._vboxwrapper: - self._vboxwrapper.send('vbox reset "{}"'.format(self._name)) - else: - self._vboxcontroller.reload() + result = self._control_vm("resume") + log.debug("VirtualBox VM has been resumed: {}".format(result)) - def resume(self): + def reload(self): """ - Resumes this VirtualBox VM. + Reloads this VirtualBox VM. """ - if self._vboxwrapper: - self._vboxwrapper.send('vbox resume "{}"'.format(self._name)) - else: - self._vboxcontroller.resume() + result = self._control_vm("reset") + log.debug("VirtualBox VM has been reset: {}".format(result)) def port_add_nio_binding(self, adapter_id, nio): """ @@ -549,14 +779,14 @@ class VirtualBoxVM(object): raise VirtualBoxError("Adapter {adapter_id} doesn't exist on VirtualBox VM {name}".format(name=self._name, adapter_id=adapter_id)) - if self._vboxwrapper: - self._vboxwrapper.send('vbox create_udp "{}" {} {} {} {}'.format(self._name, - adapter_id, - nio.lport, - nio.rhost, - nio.rport)) - else: - self._vboxcontroller.create_udp(adapter_id, nio.lport, nio.rhost, nio.rport) + vm_state = self._get_vm_state() + if vm_state == "running": + # dynamically configure an UDP tunnel on the VirtualBox adapter + self._control_vm("nic{} generic UDPTunnel".format(adapter_id + 1)) + self._control_vm("nicproperty{} sport={}".format(adapter_id + 1, nio.lport)) + self._control_vm("nicproperty{} dest={}".format(adapter_id + 1, nio.rhost)) + self._control_vm("nicproperty{} dport={}".format(adapter_id + 1, nio.rport)) + self._control_vm("setlinkstate{} on".format(adapter_id + 1)) adapter.add_nio(0, nio) log.info("VirtualBox VM {name} [id={id}]: {nio} added to adapter {adapter_id}".format(name=self._name, @@ -579,11 +809,11 @@ class VirtualBoxVM(object): raise VirtualBoxError("Adapter {adapter_id} doesn't exist on VirtualBox VM {name}".format(name=self._name, adapter_id=adapter_id)) - if self._vboxwrapper: - self._vboxwrapper.send('vbox delete_udp "{}" {}'.format(self._name, - adapter_id)) - else: - self._vboxcontroller.delete_udp(adapter_id) + vm_state = self._get_vm_state() + if vm_state == "running": + # dynamically disable the VirtualBox adapter + self._control_vm("setlinkstate{} off".format(adapter_id + 1)) + self._control_vm("nic{} null".format(adapter_id + 1)) nio = adapter.get_nio(0) adapter.remove_nio(0) @@ -620,11 +850,6 @@ class VirtualBoxVM(object): nio.startPacketCapture(output_file) - if self._vboxwrapper: - self._vboxwrapper.send('vbox create_capture "{}" {} "{}"'.format(self._name, - adapter_id, - output_file)) - log.info("VirtualBox VM {name} [id={id}]: starting packet capture on adapter {adapter_id}".format(name=self._name, id=self._id, adapter_id=adapter_id)) @@ -645,10 +870,6 @@ class VirtualBoxVM(object): nio = adapter.get_nio(0) nio.stopPacketCapture() - if self._vboxwrapper: - self._vboxwrapper.send('vbox delete_capture "{}" {}'.format(self._name, - adapter_id)) - log.info("VirtualBox VM {name} [id={id}]: stopping packet capture on adapter {adapter_id}".format(name=self._name, id=self._id, adapter_id=adapter_id))