1
0
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:
Julien Duponchelle 2016-08-25 11:49:06 +02:00
parent 21b99ad9f9
commit fc8b4c3216
No known key found for this signature in database
GPG Key ID: CE8B29639E07F5E8
5 changed files with 170 additions and 6 deletions

View File

@ -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):

View File

@ -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()

View File

@ -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):
""" """

View File

@ -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]

View File

@ -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