mirror of
https://github.com/GNS3/gns3-server.git
synced 2024-11-17 01:04:51 +02:00
Get IP address from guest Hyper-V VM. Ref https://github.com/GNS3/gns3-gui/issues/763
This commit is contained in:
parent
c9767a06b3
commit
c0521732a9
@ -404,7 +404,7 @@ class Compute:
|
|||||||
Check if remote server is accessible
|
Check if remote server is accessible
|
||||||
"""
|
"""
|
||||||
|
|
||||||
if not self._connected and not self._closed:
|
if not self._connected and not self._closed and self.host:
|
||||||
try:
|
try:
|
||||||
log.info("Connecting to compute '{}'".format(self._id))
|
log.info("Connecting to compute '{}'".format(self._id))
|
||||||
response = yield from self._run_http_query("GET", "/capabilities")
|
response = yield from self._run_http_query("GET", "/capabilities")
|
||||||
|
@ -19,6 +19,7 @@ import sys
|
|||||||
import logging
|
import logging
|
||||||
import asyncio
|
import asyncio
|
||||||
import psutil
|
import psutil
|
||||||
|
import ipaddress
|
||||||
|
|
||||||
if sys.platform.startswith("win"):
|
if sys.platform.startswith("win"):
|
||||||
import wmi
|
import wmi
|
||||||
@ -51,7 +52,7 @@ class HyperVGNS3VM(BaseGNS3VM):
|
|||||||
Checks if the GNS3 VM can run on Hyper-V.
|
Checks if the GNS3 VM can run on Hyper-V.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
if not sys.platform.startswith("win") or sys.getwindowsversion().major < 10:
|
if not sys.platform.startswith("win") or sys.getwindowsversion().major < 10:# or sys.getwindowsversion().build < 14393:
|
||||||
raise GNS3VMError("Hyper-V nested virtualization is only supported on Windows 10 and Windows Server 2016 or later")
|
raise GNS3VMError("Hyper-V nested virtualization is only supported on Windows 10 and Windows Server 2016 or later")
|
||||||
|
|
||||||
conn = wmi.WMI()
|
conn = wmi.WMI()
|
||||||
@ -62,8 +63,8 @@ class HyperVGNS3VM(BaseGNS3VM):
|
|||||||
if not conn.Win32_ComputerSystem()[0].HypervisorPresent:
|
if not conn.Win32_ComputerSystem()[0].HypervisorPresent:
|
||||||
raise GNS3VMError("Hyper-V is not installed")
|
raise GNS3VMError("Hyper-V is not installed")
|
||||||
|
|
||||||
if not conn.Win32_Processor()[0].VirtualizationFirmwareEnabled:
|
#if not conn.Win32_Processor()[0].VirtualizationFirmwareEnabled:
|
||||||
raise GNS3VMError("Nested Virtualization (VT-x) is not enabled on this system")
|
# raise GNS3VMError("Nested Virtualization (VT-x) is not enabled on this system")
|
||||||
|
|
||||||
def _connect(self):
|
def _connect(self):
|
||||||
"""
|
"""
|
||||||
@ -75,7 +76,7 @@ class HyperVGNS3VM(BaseGNS3VM):
|
|||||||
try:
|
try:
|
||||||
self._conn = wmi.WMI(namespace=r"root\virtualization\v2")
|
self._conn = wmi.WMI(namespace=r"root\virtualization\v2")
|
||||||
except wmi.x_wmi as e:
|
except wmi.x_wmi as e:
|
||||||
print("Could not connect to WMI {}".format(e))
|
raise GNS3VMError("Could not connect to WMI: {}".format(e))
|
||||||
|
|
||||||
if not self._conn.Msvm_VirtualSystemManagementService():
|
if not self._conn.Msvm_VirtualSystemManagementService():
|
||||||
raise GNS3VMError("The Windows account running GNS3 does not have the required permissions for Hyper-V")
|
raise GNS3VMError("The Windows account running GNS3 does not have the required permissions for Hyper-V")
|
||||||
@ -106,6 +107,15 @@ class HyperVGNS3VM(BaseGNS3VM):
|
|||||||
return True
|
return True
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
def _get_vm_setting_data(self, vm):
|
||||||
|
vm_settings = vm.associators(wmi_result_class='Msvm_VirtualSystemSettingData')
|
||||||
|
# Avoid snapshots
|
||||||
|
return [s for s in vm_settings if s.VirtualSystemType == 'Microsoft:Hyper-V:System:Realized'][0]
|
||||||
|
|
||||||
|
def _get_vm_resources(self, vm, resource_class):
|
||||||
|
setting_data = self._get_vm_setting_data(vm)
|
||||||
|
return setting_data.associators(wmi_result_class=resource_class)
|
||||||
|
|
||||||
def _set_vcpus_ram(self, vcpus, ram):
|
def _set_vcpus_ram(self, vcpus, ram):
|
||||||
"""
|
"""
|
||||||
Set the number of vCPU cores and amount of RAM for the GNS3 VM.
|
Set the number of vCPU cores and amount of RAM for the GNS3 VM.
|
||||||
@ -144,11 +154,14 @@ class HyperVGNS3VM(BaseGNS3VM):
|
|||||||
List all Hyper-V VMs
|
List all Hyper-V VMs
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
if self._conn is None:
|
||||||
|
self._connect()
|
||||||
|
|
||||||
vms = []
|
vms = []
|
||||||
try:
|
try:
|
||||||
for vm in self._conn.Msvm_ComputerSystem():
|
for vm in self._conn.Msvm_ComputerSystem():
|
||||||
if vm.Caption == "Virtual Machine":
|
if vm.Caption == "Virtual Machine":
|
||||||
vms.append(vm.ElementName)
|
vms.append({"vmname": vm.ElementName})
|
||||||
except wmi.x_wmi as e:
|
except wmi.x_wmi as e:
|
||||||
raise GNS3VMError("Could not list Hyper-V VMs: {}".format(e))
|
raise GNS3VMError("Could not list Hyper-V VMs: {}".format(e))
|
||||||
return vms
|
return vms
|
||||||
@ -186,6 +199,9 @@ class HyperVGNS3VM(BaseGNS3VM):
|
|||||||
if self._conn is None:
|
if self._conn is None:
|
||||||
self._connect()
|
self._connect()
|
||||||
|
|
||||||
|
if not self._vm:
|
||||||
|
raise GNS3VMError("Could not find Hyper-V VM {}".format(self.vmname))
|
||||||
|
|
||||||
if not self._is_running():
|
if not self._is_running():
|
||||||
|
|
||||||
log.info("Update GNS3 VM settings")
|
log.info("Update GNS3 VM settings")
|
||||||
@ -199,9 +215,35 @@ class HyperVGNS3VM(BaseGNS3VM):
|
|||||||
raise GNS3VMError("Failed to start the GNS3 VM: {}".format(e))
|
raise GNS3VMError("Failed to start the GNS3 VM: {}".format(e))
|
||||||
log.info("GNS3 VM has been started")
|
log.info("GNS3 VM has been started")
|
||||||
|
|
||||||
#TODO: get the guest IP address
|
# Get the guest IP address
|
||||||
#self.ip_address = guest_ip_address
|
trial = 120
|
||||||
#log.info("GNS3 VM IP address set to {}".format(guest_ip_address))
|
guest_ip_address = ""
|
||||||
|
log.info("Waiting for GNS3 VM IP")
|
||||||
|
ports = self._get_vm_resources(self._vm, 'Msvm_EthernetPortAllocationSettingData')
|
||||||
|
vnics = self._get_vm_resources(self._vm, 'Msvm_SyntheticEthernetPortSettingData')
|
||||||
|
while True:
|
||||||
|
for port in ports:
|
||||||
|
vnic = [v for v in vnics if port.Parent == v.path_()][0]
|
||||||
|
config = vnic.associators(wmi_result_class='Msvm_GuestNetworkAdapterConfiguration')
|
||||||
|
ip_addresses = config[0].IPAddresses
|
||||||
|
for ip_address in ip_addresses:
|
||||||
|
# take the first valid IPv4 address
|
||||||
|
try:
|
||||||
|
ipaddress.IPv4Address(ip_address)
|
||||||
|
guest_ip_address = ip_address
|
||||||
|
except ipaddress.AddressValueError:
|
||||||
|
continue
|
||||||
|
if len(ip_addresses):
|
||||||
|
guest_ip_address = ip_addresses[0]
|
||||||
|
break
|
||||||
|
trial -= 1
|
||||||
|
if guest_ip_address:
|
||||||
|
break
|
||||||
|
elif trial == 0:
|
||||||
|
raise GNS3VMError("Could not find guest IP address for {}".format(self.vmname))
|
||||||
|
yield from asyncio.sleep(1)
|
||||||
|
self.ip_address = guest_ip_address
|
||||||
|
log.info("GNS3 VM IP address set to {}".format(guest_ip_address))
|
||||||
self.running = True
|
self.running = True
|
||||||
|
|
||||||
@asyncio.coroutine
|
@asyncio.coroutine
|
||||||
@ -210,8 +252,8 @@ class HyperVGNS3VM(BaseGNS3VM):
|
|||||||
Suspend the GNS3 VM.
|
Suspend the GNS3 VM.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
if self._conn is None:
|
if self.running is False:
|
||||||
self._connect()
|
return
|
||||||
|
|
||||||
try:
|
try:
|
||||||
yield from self._set_state(HyperVGNS3VM._HYPERV_VM_STATE_PAUSED)
|
yield from self._set_state(HyperVGNS3VM._HYPERV_VM_STATE_PAUSED)
|
||||||
@ -226,9 +268,8 @@ class HyperVGNS3VM(BaseGNS3VM):
|
|||||||
Stops the GNS3 VM.
|
Stops the GNS3 VM.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
if self._conn is None:
|
if self.running is False:
|
||||||
self._connect()
|
return
|
||||||
|
|
||||||
try:
|
try:
|
||||||
yield from self._set_state(HyperVGNS3VM._HYPERV_VM_STATE_DISABLED)
|
yield from self._set_state(HyperVGNS3VM._HYPERV_VM_STATE_DISABLED)
|
||||||
except GNS3VMError as e:
|
except GNS3VMError as e:
|
||||||
|
Loading…
Reference in New Issue
Block a user