mirror of
https://github.com/GNS3/gns3-server
synced 2024-11-24 17:28:08 +00:00
Start GNS3 VM with the controller
Ref https://github.com/GNS3/gns3-gui/issues/1254
This commit is contained in:
parent
21b99ad9f9
commit
fc8b4c3216
@ -62,6 +62,7 @@ class Controller:
|
|||||||
@asyncio.coroutine
|
@asyncio.coroutine
|
||||||
def start(self):
|
def start(self):
|
||||||
log.info("Start controller")
|
log.info("Start controller")
|
||||||
|
yield from self.load()
|
||||||
server_config = Config.instance().get_section_config("Server")
|
server_config = Config.instance().get_section_config("Server")
|
||||||
self._computes["local"] = Compute(compute_id="local",
|
self._computes["local"] = Compute(compute_id="local",
|
||||||
controller=self,
|
controller=self,
|
||||||
@ -70,7 +71,16 @@ class Controller:
|
|||||||
port=server_config.getint("port", 3080),
|
port=server_config.getint("port", 3080),
|
||||||
user=server_config.get("user", ""),
|
user=server_config.get("user", ""),
|
||||||
password=server_config.get("password", ""))
|
password=server_config.get("password", ""))
|
||||||
yield from self.load()
|
if self.gns3vm.enable:
|
||||||
|
yield from self.gns3vm.start()
|
||||||
|
self._computes["vm"] = Compute(compute_id="vm",
|
||||||
|
name="GNS3 VM",
|
||||||
|
controller=self,
|
||||||
|
protocol=self.gns3vm.protocol,
|
||||||
|
host=self.gns3vm.ip_address,
|
||||||
|
port=self.gns3vm.port,
|
||||||
|
user=self.gns3vm.user,
|
||||||
|
password=self.gns3vm.password)
|
||||||
|
|
||||||
@asyncio.coroutine
|
@asyncio.coroutine
|
||||||
def stop(self):
|
def stop(self):
|
||||||
|
@ -21,6 +21,9 @@ import asyncio
|
|||||||
from .vmware_gns3_vm import VMwareGNS3VM
|
from .vmware_gns3_vm import VMwareGNS3VM
|
||||||
from .virtualbox_gns3_vm import VirtualBoxGNS3VM
|
from .virtualbox_gns3_vm import VirtualBoxGNS3VM
|
||||||
|
|
||||||
|
import logging
|
||||||
|
log = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
class GNS3VM:
|
class GNS3VM:
|
||||||
"""
|
"""
|
||||||
@ -62,6 +65,61 @@ class GNS3VM:
|
|||||||
virtualbox_informations
|
virtualbox_informations
|
||||||
]
|
]
|
||||||
|
|
||||||
|
def _current_engine(self):
|
||||||
|
return self._get_engine(self._settings["engine"])
|
||||||
|
|
||||||
|
@property
|
||||||
|
def ip_address(self):
|
||||||
|
"""
|
||||||
|
Returns the GNS3 VM IP address.
|
||||||
|
|
||||||
|
:returns: VM IP address
|
||||||
|
"""
|
||||||
|
return self._current_engine().ip_address
|
||||||
|
|
||||||
|
@property
|
||||||
|
def user(self):
|
||||||
|
"""
|
||||||
|
Returns the GNS3 VM user.
|
||||||
|
|
||||||
|
:returns: VM user
|
||||||
|
"""
|
||||||
|
return self._current_engine().user
|
||||||
|
|
||||||
|
@property
|
||||||
|
def password(self):
|
||||||
|
"""
|
||||||
|
Returns the GNS3 VM password.
|
||||||
|
|
||||||
|
:returns: VM password
|
||||||
|
"""
|
||||||
|
return self._current_engine().password
|
||||||
|
|
||||||
|
@property
|
||||||
|
def port(self):
|
||||||
|
"""
|
||||||
|
Returns the GNS3 VM port.
|
||||||
|
|
||||||
|
:returns: VM port
|
||||||
|
"""
|
||||||
|
return self._current_engine().port
|
||||||
|
|
||||||
|
@property
|
||||||
|
def protocol(self):
|
||||||
|
"""
|
||||||
|
Returns the GNS3 VM protocol.
|
||||||
|
|
||||||
|
:returns: VM protocol
|
||||||
|
"""
|
||||||
|
return self._current_engine().protocol
|
||||||
|
|
||||||
|
@property
|
||||||
|
def enable(self):
|
||||||
|
"""
|
||||||
|
The GNSVM is activated
|
||||||
|
"""
|
||||||
|
return self._settings["enable"]
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def settings(self):
|
def settings(self):
|
||||||
return self._settings
|
return self._settings
|
||||||
@ -99,3 +157,15 @@ class GNS3VM:
|
|||||||
for vm in (yield from engine.list()):
|
for vm in (yield from engine.list()):
|
||||||
vms.append({"vmname": vm["vmname"]})
|
vms.append({"vmname": vm["vmname"]})
|
||||||
return vms
|
return vms
|
||||||
|
|
||||||
|
@asyncio.coroutine
|
||||||
|
def start(self):
|
||||||
|
"""
|
||||||
|
Start the GNS3 VM
|
||||||
|
"""
|
||||||
|
engine = self._current_engine()
|
||||||
|
if not engine.running:
|
||||||
|
log.info("Start the GNS3 VM")
|
||||||
|
engine.vmname = self._settings["vmname"]
|
||||||
|
yield from engine.start()
|
||||||
|
|
||||||
|
@ -33,15 +33,21 @@ class BaseGNS3VM:
|
|||||||
self._headless = False
|
self._headless = False
|
||||||
self._vcpus = 1
|
self._vcpus = 1
|
||||||
self._ram = 1024
|
self._ram = 1024
|
||||||
|
self._user = ""
|
||||||
|
self.password = ""
|
||||||
|
self._protocol = "http"
|
||||||
self._running = False
|
self._running = False
|
||||||
|
|
||||||
# limit the number of vCPUs to the number of physical cores (hyper thread CPUs are excluded)
|
# limit the number of vCPUs to the number of physical cores (hyper thread CPUs are excluded)
|
||||||
# because this is likely to degrade performances.
|
# because this is likely to degrade performances.
|
||||||
self._vcpus = psutil.cpu_count(logical=False)
|
self._vcpus = psutil.cpu_count(logical=False)
|
||||||
# we want to allocate half of the available physical memory
|
# we want to allocate half of the available physical memory
|
||||||
ram = int(psutil.virtual_memory().total / (1024 * 1024) / 2)
|
#ram = int(psutil.virtual_memory().total / (1024 * 1024) / 2)
|
||||||
# value must be a multiple of 4 (VMware requirement)
|
# value must be a multiple of 4 (VMware requirement)
|
||||||
ram -= ram % 4
|
#ram -= ram % 4
|
||||||
|
|
||||||
|
ram = 2048
|
||||||
|
|
||||||
self._ram = ram
|
self._ram = ram
|
||||||
|
|
||||||
@property
|
@property
|
||||||
@ -64,6 +70,60 @@ class BaseGNS3VM:
|
|||||||
|
|
||||||
self._vmname = new_name
|
self._vmname = new_name
|
||||||
|
|
||||||
|
@property
|
||||||
|
def protocol(self):
|
||||||
|
"""
|
||||||
|
Get the GNS3 VM protocol
|
||||||
|
|
||||||
|
:returns: Protocol as string
|
||||||
|
"""
|
||||||
|
return self._protocol
|
||||||
|
|
||||||
|
@protocol.setter
|
||||||
|
def protocol(self, val):
|
||||||
|
"""
|
||||||
|
Sets the GNS3 VM protocol
|
||||||
|
|
||||||
|
:param val: new VM protocol
|
||||||
|
"""
|
||||||
|
self._protocol = val
|
||||||
|
|
||||||
|
@property
|
||||||
|
def user(self):
|
||||||
|
"""
|
||||||
|
Get the GNS3 VM user
|
||||||
|
|
||||||
|
:returns: User as string
|
||||||
|
"""
|
||||||
|
return self._user
|
||||||
|
|
||||||
|
@user.setter
|
||||||
|
def user(self, val):
|
||||||
|
"""
|
||||||
|
Sets the GNS3 VM user
|
||||||
|
|
||||||
|
:param val: new VM user
|
||||||
|
"""
|
||||||
|
self._user = val
|
||||||
|
|
||||||
|
@property
|
||||||
|
def password(self):
|
||||||
|
"""
|
||||||
|
Get the GNS3 VM password
|
||||||
|
|
||||||
|
:returns: Password as string
|
||||||
|
"""
|
||||||
|
return self._password
|
||||||
|
|
||||||
|
@password.setter
|
||||||
|
def password(self, val):
|
||||||
|
"""
|
||||||
|
Sets the GNS3 VM password
|
||||||
|
|
||||||
|
:param val: new VM password
|
||||||
|
"""
|
||||||
|
self._password = val
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def port(self):
|
def port(self):
|
||||||
"""
|
"""
|
||||||
|
@ -59,9 +59,10 @@ class VMwareGNS3VM(BaseGNS3VM):
|
|||||||
|
|
||||||
available_ram = int(psutil.virtual_memory().available / (1024 * 1024))
|
available_ram = int(psutil.virtual_memory().available / (1024 * 1024))
|
||||||
if ram > available_ram:
|
if ram > available_ram:
|
||||||
raise GNS3VMError("You have allocated too much memory for the GNS3 VM! (available memory is {} MB)".format(available_ram))
|
raise GNS3VMError("You have allocated too much memory ({} MB) for the GNS3 VM! (available memory is {} MB)".format(ram, available_ram))
|
||||||
|
|
||||||
# memory must be a multiple of 4 (VMware requirement)
|
# memory must be a multiple of 4 (VMware requirement)
|
||||||
|
|
||||||
if ram % 4 != 0:
|
if ram % 4 != 0:
|
||||||
raise GNS3VMError("Allocated memory for the GNS3 VM must be a multiple of 4".format(available_ram))
|
raise GNS3VMError("Allocated memory for the GNS3 VM must be a multiple of 4".format(available_ram))
|
||||||
|
|
||||||
@ -100,12 +101,12 @@ class VMwareGNS3VM(BaseGNS3VM):
|
|||||||
|
|
||||||
# check we have a valid VMX file path
|
# check we have a valid VMX file path
|
||||||
if not self._vmx_path:
|
if not self._vmx_path:
|
||||||
raise GNS3VMError("GNS3 VM is not configured")
|
raise GNS3VMError("VMWare VM {} not found".format(self.vmname))
|
||||||
if not os.path.exists(self._vmx_path):
|
if not os.path.exists(self._vmx_path):
|
||||||
raise GNS3VMError("VMware VMX file {} doesn't exist".format(self._vmx_path))
|
raise GNS3VMError("VMware VMX file {} doesn't exist".format(self._vmx_path))
|
||||||
|
|
||||||
# set the number of vCPUs and amount of RAM
|
# set the number of vCPUs and amount of RAM
|
||||||
yield from self._set_vcpus_ram(self.vcpus, self.ram)
|
#yield from self._set_vcpus_ram(self.vcpus, self.ram)
|
||||||
|
|
||||||
# start the VM
|
# start the VM
|
||||||
args = [self._vmx_path]
|
args = [self._vmx_path]
|
||||||
|
@ -19,6 +19,7 @@ import os
|
|||||||
import uuid
|
import uuid
|
||||||
import json
|
import json
|
||||||
import pytest
|
import pytest
|
||||||
|
import socket
|
||||||
import aiohttp
|
import aiohttp
|
||||||
from unittest.mock import MagicMock
|
from unittest.mock import MagicMock
|
||||||
from tests.utils import AsyncioMagicMock, asyncio_patch
|
from tests.utils import AsyncioMagicMock, asyncio_patch
|
||||||
@ -252,6 +253,28 @@ def test_getProject(controller, async_run):
|
|||||||
assert controller.get_project("dsdssd")
|
assert controller.get_project("dsdssd")
|
||||||
|
|
||||||
|
|
||||||
|
def test_start(controller, async_run):
|
||||||
|
async_run(controller.start())
|
||||||
|
assert len(controller.computes) == 1 # Local compute is created
|
||||||
|
assert controller.computes["local"].name == socket.gethostname()
|
||||||
|
|
||||||
|
|
||||||
|
def test_start_vm(controller, async_run):
|
||||||
|
"""
|
||||||
|
Start the controller with a GNS3 VM
|
||||||
|
"""
|
||||||
|
controller.gns3vm.settings = {
|
||||||
|
"enable": True,
|
||||||
|
"engine": "vmware"
|
||||||
|
}
|
||||||
|
with asyncio_patch("gns3server.controller.gns3vm.vmware_gns3_vm.VMwareGNS3VM.start") as mock:
|
||||||
|
async_run(controller.start())
|
||||||
|
assert mock.called
|
||||||
|
assert len(controller.computes) == 2 # Local compute and vm are created
|
||||||
|
assert "local" in controller.computes
|
||||||
|
assert "vm" in controller.computes
|
||||||
|
|
||||||
|
|
||||||
def test_stop(controller, async_run):
|
def test_stop(controller, async_run):
|
||||||
c = async_run(controller.add_compute(compute_id="test1"))
|
c = async_run(controller.add_compute(compute_id="test1"))
|
||||||
c._connected = True
|
c._connected = True
|
||||||
|
Loading…
Reference in New Issue
Block a user