mirror of
https://github.com/GNS3/gns3-server.git
synced 2024-12-30 09:38:53 +00:00
Merge branch '2.2' into 3.0
# Conflicts: # gns3server/controller/__init__.py # gns3server/controller/compute.py # gns3server/schemas/gns3vm.py # gns3server/utils/application_id.py # gns3server/version.py # gns3server/web/web_server.py
This commit is contained in:
commit
a5d89b428a
11
CHANGELOG
11
CHANGELOG
@ -1,5 +1,16 @@
|
||||
# Change Log
|
||||
|
||||
## 2.2.16 05/11/2020
|
||||
|
||||
* Option to allocate or not the vCPUs and RAM settings for the GNS3 VM. Fixes https://github.com/GNS3/gns3-gui/issues/3069
|
||||
* Release Web UI version 2.2.16
|
||||
* Fix wrong defaults for images_path, configs_path, appliances_path. Fixes #1829
|
||||
* Use EnvironmentFile for Systemd service. Ref https://github.com/GNS3/gns3-gui/issues/3048
|
||||
* Fix SSL support for controller and local compute. Fixes #1826
|
||||
* Prevent WIC to be added/removed while Dynamips router is running. Fixes https://github.com/GNS3/gns3-gui/issues/3082
|
||||
* Fix bug with application id allocation for IOU nodes. Fixes #3079
|
||||
* Allow commas in image paths and VM name for Qemu VMs. Fixes https://github.com/GNS3/gns3-gui/issues/3065
|
||||
|
||||
## 2.2.15 07/10/2020
|
||||
|
||||
* Fix symbol retrieval issue. Ref #1824
|
||||
|
@ -27,10 +27,17 @@
|
||||
},
|
||||
"images": [
|
||||
{
|
||||
"filename": "vEOS-lab-4.25.0FX-LDP-RSVP.vmdk",
|
||||
"version": "4.25.0FX",
|
||||
"md5sum": "b7c2efdbe48301a78f124db989710346",
|
||||
"filesize": 468647936,
|
||||
"filename": "vEOS-lab-4.25.0F.vmdk",
|
||||
"version": "4.25.0F",
|
||||
"md5sum": "d420763fdf3bc50e7e5b88418bd9d1fd",
|
||||
"filesize": 468779008,
|
||||
"download_url": "https://www.arista.com/en/support/software-download"
|
||||
},
|
||||
{
|
||||
"filename": "vEOS-lab-4.24.3M.vmdk",
|
||||
"version": "4.24.3M",
|
||||
"md5sum": "0a28e44c7ce4a8965f24a4a463a89b7d",
|
||||
"filesize": 455213056,
|
||||
"download_url": "https://www.arista.com/en/support/software-download"
|
||||
},
|
||||
{
|
||||
@ -204,10 +211,17 @@
|
||||
],
|
||||
"versions": [
|
||||
{
|
||||
"name": "4.25.0FX",
|
||||
"name": "4.25.0F",
|
||||
"images": {
|
||||
"hda_disk_image": "Aboot-veos-serial-8.0.0.iso",
|
||||
"hdb_disk_image": "vEOS-lab-4.25.0FX-LDP-RSVP.vmdk"
|
||||
"hdb_disk_image": "vEOS-lab-4.25.0F.vmdk"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "4.24.3M",
|
||||
"images": {
|
||||
"hda_disk_image": "Aboot-veos-serial-8.0.0.iso",
|
||||
"hdb_disk_image": "vEOS-lab-4.24.3M.vmdk"
|
||||
}
|
||||
},
|
||||
{
|
||||
|
@ -20,7 +20,8 @@
|
||||
"hda_disk_interface": "virtio",
|
||||
"arch": "x86_64",
|
||||
"console_type": "telnet",
|
||||
"kvm": "require"
|
||||
"kvm": "require",
|
||||
"options": "-machine pc-q35-4.2"
|
||||
},
|
||||
"images": [
|
||||
{
|
||||
|
@ -26,6 +26,13 @@
|
||||
"options": "-nographic"
|
||||
},
|
||||
"images": [
|
||||
{
|
||||
"filename": "VOSSGNS3.8.2.0.0.qcow2",
|
||||
"version": "v8.2.0.0",
|
||||
"md5sum": "9a0cd77c08644abbf3a69771c125c011",
|
||||
"filesize": 331808768,
|
||||
"direct_download_url": "https://akamai-ep.extremenetworks.com/Extreme_P/github-en/Virtual_VOSS/VOSSGNS3.8.2.0.0.qcow2"
|
||||
},
|
||||
{
|
||||
"filename": "VOSSGNS3.8.1.5.0.qcow2",
|
||||
"version": "8.1.5.0",
|
||||
@ -56,6 +63,12 @@
|
||||
}
|
||||
],
|
||||
"versions": [
|
||||
{
|
||||
"name": "v8.2.0.0",
|
||||
"images": {
|
||||
"hda_disk_image": "VOSSGNS3.8.2.0.0.qcow2"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "8.1.5.0",
|
||||
"images": {
|
||||
|
@ -27,6 +27,20 @@
|
||||
"options": "-smp 2 -cpu host"
|
||||
},
|
||||
"images": [
|
||||
{
|
||||
"filename": "BIGIP-16.0.0.1-0.0.3.qcow2",
|
||||
"version": "16.0.0.1",
|
||||
"md5sum": "95ff618b7d0b53c4252299cd49b0e564",
|
||||
"filesize": 5393088512,
|
||||
"download_url": "https://downloads.f5.com/esd/serveDownload.jsp?path=/big-ip/big-ip_v16.x/16.0.0/english/16.0.0.1_virtual-edition/&sw=BIG-IP&pro=big-ip_v16.x&ver=16.0.0&container=16.0.0.1_Virtual-Edition&file=BIGIP-16.0.0.1-0.0.3.ALL.qcow2.zip"
|
||||
},
|
||||
{
|
||||
"filename": "BIGIP-16.0.0-0.0.12.qcow2",
|
||||
"version": "16.0.0",
|
||||
"md5sum": "c49cd2513e386f3259eb0ee6fe3bb502",
|
||||
"filesize": 5344722944,
|
||||
"download_url": "https://downloads.f5.com/esd/serveDownload.jsp?path=/big-ip/big-ip_v16.x/16.0.0/english/16.0.0_virtual-edition/&sw=BIG-IP&pro=big-ip_v16.x&ver=16.0.0&container=16.0.0_Virtual-Edition&file=BIGIP-16.0.0-0.0.12.ALL.qcow2.zip"
|
||||
},
|
||||
{
|
||||
"filename": "BIGIP-15.1.0.2-0.0.9.qcow2",
|
||||
"version": "15.1.0.2",
|
||||
@ -163,6 +177,20 @@
|
||||
}
|
||||
],
|
||||
"versions": [
|
||||
{
|
||||
"name": "16.0.0.1",
|
||||
"images": {
|
||||
"hda_disk_image": "BIGIP-16.0.0.1-0.0.3.qcow2",
|
||||
"hdb_disk_image": "empty100G.qcow2"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "16.0.0",
|
||||
"images": {
|
||||
"hda_disk_image": "BIGIP-16.0.0-0.0.12.qcow2",
|
||||
"hdb_disk_image": "empty100G.qcow2"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "15.1.0.2",
|
||||
"images": {
|
||||
|
@ -25,31 +25,31 @@
|
||||
},
|
||||
"images": [
|
||||
{
|
||||
"filename": "OPNsense-18.1.6-OpenSSL-nano-amd64.img",
|
||||
"version": "18.1.6",
|
||||
"md5sum": "042f328380ad0c8008759c43435e8843",
|
||||
"filesize": 272003136,
|
||||
"download_url": "https://opnsense.c0urier.net/releases/18.1/"
|
||||
"filename": "OPNsense-20.7-OpenSSL-nano-amd64.img",
|
||||
"version": "20.7",
|
||||
"md5sum": "453e505e9526d4a0a3d5208efdd13b1a",
|
||||
"filesize": 3221225472,
|
||||
"download_url": "https://opnsense.c0urier.net/releases/20.7/"
|
||||
},
|
||||
{
|
||||
"filename": "OPNsense-17.7.5-OpenSSL-nano-amd64.img",
|
||||
"version": "17.7.5",
|
||||
"md5sum": "6ec5b7f99cc727f904bbf2aaadcab0b8",
|
||||
"filesize": 237038601,
|
||||
"download_url": "https://opnsense.c0urier.net/releases/17.7/"
|
||||
"filename": "OPNsense-19.7-OpenSSL-nano-amd64.img",
|
||||
"version": "19.7",
|
||||
"md5sum": "a15a00cfa2de45791d6bc230d8469dc7",
|
||||
"filesize": 3221225472,
|
||||
"download_url": "https://opnsense.c0urier.net/releases/19.7/"
|
||||
}
|
||||
],
|
||||
"versions": [
|
||||
{
|
||||
"name": "18.1.6",
|
||||
"name": "20.7",
|
||||
"images": {
|
||||
"hda_disk_image": "OPNsense-18.1.6-OpenSSL-nano-amd64.img"
|
||||
"hda_disk_image": "OPNsense-20.7-OpenSSL-nano-amd64.img"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "17.7.5",
|
||||
"name": "19.7",
|
||||
"images": {
|
||||
"hda_disk_image": "OPNsense-17.7.5-OpenSSL-nano-amd64.img"
|
||||
"hda_disk_image": "OPNsense-19.7-OpenSSL-nano-amd64.img"
|
||||
}
|
||||
}
|
||||
]
|
||||
|
@ -11,12 +11,12 @@
|
||||
"status": "stable",
|
||||
"maintainer": "GNS3 Team",
|
||||
"maintainer_email": "developers@gns3.net",
|
||||
"usage": "Credentials: SSH ---> username: root ---> password: 1234 MySQL DB: ---> username: root --> password: tacacs Web interface: ---> username: tacgui ---> password: abc123",
|
||||
"usage": "Credentials:\nSSH ---> username: root ---> password: 1234\nMySQL DB: ---> username: root --> password: tacacs\nWeb interface: ---> username: tacgui ---> password: abc123\n\nDefault for 0.9.82 or above:\nIP Address: 10.0.0.254\nNetmask: 255.0.0.0\nGateway: 10.0.0.1",
|
||||
"port_name_format": "Port{port1}",
|
||||
"qemu": {
|
||||
"adapter_type": "e1000",
|
||||
"adapters": 1,
|
||||
"ram": 1024,
|
||||
"ram": 4096,
|
||||
"hda_disk_interface": "ide",
|
||||
"arch": "x86_64",
|
||||
"console_type": "telnet",
|
||||
@ -24,6 +24,13 @@
|
||||
"kvm": "allow"
|
||||
},
|
||||
"images": [
|
||||
{
|
||||
"filename": "tacgui-0.9.82-20201008.qcow2",
|
||||
"version": "0.9.82",
|
||||
"md5sum": "dc0c84aa61d8960a23bf3b309a826f3f",
|
||||
"filesize": 2914844672,
|
||||
"download_url": "https://drive.google.com/open?id=1tlDSyoD5dAWgJu6I76CgYV7BkwhScWSS"
|
||||
},
|
||||
{
|
||||
"filename": "tac_plus.qcow2",
|
||||
"version": "201710201114",
|
||||
@ -33,6 +40,12 @@
|
||||
}
|
||||
],
|
||||
"versions": [
|
||||
{
|
||||
"name": "0.9.82",
|
||||
"images": {
|
||||
"hda_disk_image": "tacgui-0.9.82-20201008.qcow2"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "201710201114",
|
||||
"images": {
|
||||
|
@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "Tiny Core Linux",
|
||||
"category": "guest",
|
||||
"description": "Core Linux is a smaller variant of Tiny Core without a graphical desktop.\n\nIt's provide a complete Linux system in few MB.",
|
||||
"description": "Core Linux is a smaller variant of Tiny Core without a graphical desktop.\n\nIt provides a complete Linux system using only a few MiB." ,
|
||||
"vendor_name": "Team Tiny Core",
|
||||
"vendor_url": "http://distro.ibiblio.org/tinycorelinux",
|
||||
"documentation_url": "http://wiki.tinycorelinux.net/",
|
||||
|
@ -25,6 +25,13 @@
|
||||
"options": "-vga virtio"
|
||||
},
|
||||
"images": [
|
||||
{
|
||||
"filename": "Ubuntu 20.04 (64bit).vmdk",
|
||||
"version": "20.04",
|
||||
"md5sum": "cf619dfe9bb8d89e2b18b067f02e57a0",
|
||||
"filesize": 6629883904,
|
||||
"download_url": "http://www.osboxes.org/ubuntu/"
|
||||
},
|
||||
{
|
||||
"filename": "Ubuntu 19.04 (64bit).vmdk",
|
||||
"version": "19.04",
|
||||
@ -55,6 +62,12 @@
|
||||
}
|
||||
],
|
||||
"versions": [
|
||||
{
|
||||
"name": "20.04",
|
||||
"images": {
|
||||
"hda_disk_image": "Ubuntu 20.04 (64bit).vmdk"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "19.04",
|
||||
"images": {
|
||||
|
@ -1184,13 +1184,17 @@ class Router(BaseNode):
|
||||
if not adapter.wic_slot_available(wic_slot_number):
|
||||
raise DynamipsError("WIC slot {wic_slot_number} is already occupied by another WIC".format(wic_slot_number=wic_slot_number))
|
||||
|
||||
if await self.is_running():
|
||||
raise DynamipsError('WIC "{wic}" cannot be added while router "{name}" is running'.format(wic=wic,
|
||||
name=self._name))
|
||||
|
||||
# Dynamips WICs slot IDs start on a multiple of 16
|
||||
# WIC1 = 16, WIC2 = 32 and WIC3 = 48
|
||||
internal_wic_slot_number = 16 * (wic_slot_number + 1)
|
||||
await self._hypervisor.send('vm slot_add_binding "{name}" {slot_number} {wic_slot_number} {wic}'.format(name=self._name,
|
||||
slot_number=slot_number,
|
||||
wic_slot_number=internal_wic_slot_number,
|
||||
wic=wic))
|
||||
slot_number=slot_number,
|
||||
wic_slot_number=internal_wic_slot_number,
|
||||
wic=wic))
|
||||
|
||||
log.info('Router "{name}" [{id}]: {wic} inserted into WIC slot {wic_slot_number}'.format(name=self._name,
|
||||
id=self._id,
|
||||
@ -1219,12 +1223,16 @@ class Router(BaseNode):
|
||||
if adapter.wic_slot_available(wic_slot_number):
|
||||
raise DynamipsError("No WIC is installed in WIC slot {wic_slot_number}".format(wic_slot_number=wic_slot_number))
|
||||
|
||||
if await self.is_running():
|
||||
raise DynamipsError('WIC cannot be removed from slot {wic_slot_number} while router "{name}" is running'.format(wic_slot_number=wic_slot_number,
|
||||
name=self._name))
|
||||
|
||||
# Dynamips WICs slot IDs start on a multiple of 16
|
||||
# WIC1 = 16, WIC2 = 32 and WIC3 = 48
|
||||
internal_wic_slot_number = 16 * (wic_slot_number + 1)
|
||||
await self._hypervisor.send('vm slot_remove_binding "{name}" {slot_number} {wic_slot_number}'.format(name=self._name,
|
||||
slot_number=slot_number,
|
||||
wic_slot_number=internal_wic_slot_number))
|
||||
slot_number=slot_number,
|
||||
wic_slot_number=internal_wic_slot_number))
|
||||
|
||||
log.info('Router "{name}" [{id}]: {wic} removed from WIC slot {wic_slot_number}'.format(name=self._name,
|
||||
id=self._id,
|
||||
|
@ -268,7 +268,7 @@ class Controller:
|
||||
"""
|
||||
|
||||
server_config = Config.instance().get_section_config("Server")
|
||||
images_path = os.path.expanduser(server_config.get("images_path", "~/GNS3/projects"))
|
||||
images_path = os.path.expanduser(server_config.get("images_path", "~/GNS3/images"))
|
||||
os.makedirs(images_path, exist_ok=True)
|
||||
return images_path
|
||||
|
||||
@ -278,9 +278,9 @@ class Controller:
|
||||
"""
|
||||
|
||||
server_config = Config.instance().get_section_config("Server")
|
||||
images_path = os.path.expanduser(server_config.get("configs_path", "~/GNS3/projects"))
|
||||
os.makedirs(images_path, exist_ok=True)
|
||||
return images_path
|
||||
configs_path = os.path.expanduser(server_config.get("configs_path", "~/GNS3/configs"))
|
||||
os.makedirs(configs_path, exist_ok=True)
|
||||
return configs_path
|
||||
|
||||
async def add_compute(self, compute_id=None, name=None, force=False, connect=True, **kwargs):
|
||||
"""
|
||||
|
@ -71,7 +71,7 @@ class ApplianceManager:
|
||||
"""
|
||||
|
||||
server_config = Config.instance().get_section_config("Server")
|
||||
appliances_path = os.path.expanduser(server_config.get("appliances_path", "~/GNS3/projects"))
|
||||
appliances_path = os.path.expanduser(server_config.get("appliances_path", "~/GNS3/appliances"))
|
||||
os.makedirs(appliances_path, exist_ok=True)
|
||||
return appliances_path
|
||||
|
||||
|
@ -64,8 +64,8 @@ class Compute:
|
||||
A GNS3 compute.
|
||||
"""
|
||||
|
||||
def __init__(self, compute_id, controller=None, protocol="http", host="localhost", port=3080, user=None,
|
||||
password=None, name=None, console_host=None):
|
||||
def __init__(self, compute_id, controller=None, protocol="http", host="localhost",
|
||||
port=3080, user=None, password=None, name=None, console_host=None, ssl_context=None):
|
||||
self._http_session = None
|
||||
assert controller is not None
|
||||
log.info("Create compute %s", compute_id)
|
||||
@ -90,6 +90,7 @@ class Compute:
|
||||
self._memory_usage_percent = 0
|
||||
self._disk_usage_percent = 0
|
||||
self._last_error = None
|
||||
self._ssl_context = ssl_context
|
||||
self._capabilities = {
|
||||
"version": "",
|
||||
"platform": "",
|
||||
@ -105,7 +106,7 @@ class Compute:
|
||||
|
||||
def _session(self):
|
||||
if self._http_session is None or self._http_session.closed is True:
|
||||
connector = aiohttp.TCPConnector(force_close=True)
|
||||
connector = aiohttp.TCPConnector(force_close=True, ssl_context=self._ssl_context)
|
||||
self._http_session = aiohttp.ClientSession(connector=connector)
|
||||
return self._http_session
|
||||
|
||||
|
@ -49,6 +49,7 @@ class GNS3VM:
|
||||
"headless": False,
|
||||
"enable": False,
|
||||
"engine": "vmware",
|
||||
"allocate_vcpus_ram": True,
|
||||
"ram": 2048,
|
||||
"vcpus": 1,
|
||||
"port": 80,
|
||||
@ -311,6 +312,7 @@ class GNS3VM:
|
||||
if self._settings["vmname"] is None:
|
||||
return
|
||||
log.info("Start the GNS3 VM")
|
||||
engine.allocate_vcpus_ram = self._settings["allocate_vcpus_ram"]
|
||||
engine.vmname = self._settings["vmname"]
|
||||
engine.ram = self._settings["ram"]
|
||||
engine.vcpus = self._settings["vcpus"]
|
||||
|
@ -30,6 +30,7 @@ class BaseGNS3VM:
|
||||
self._ip_address = None
|
||||
self._port = 80 # value not used, will be overwritten
|
||||
self._headless = False
|
||||
self._allocate_vcpus_ram = True
|
||||
self._vcpus = 1
|
||||
self._ram = 1024
|
||||
self._user = ""
|
||||
@ -203,6 +204,26 @@ class BaseGNS3VM:
|
||||
|
||||
self._headless = value
|
||||
|
||||
@property
|
||||
def allocate_vcpus_ram(self):
|
||||
"""
|
||||
Returns whether VCPUs and RAM settings should be configured for the GNS3 VM.
|
||||
|
||||
:returns: boolean
|
||||
"""
|
||||
|
||||
return self._allocate_vcpus_ram
|
||||
|
||||
@allocate_vcpus_ram.setter
|
||||
def allocate_vcpus_ram(self, value):
|
||||
"""
|
||||
Sets whether VCPUs and RAM settings should be configured for the GNS3 VM.
|
||||
|
||||
:param value: boolean
|
||||
"""
|
||||
|
||||
self._allocate_vcpus_ram = value
|
||||
|
||||
@property
|
||||
def vcpus(self):
|
||||
"""
|
||||
|
@ -251,9 +251,10 @@ class HyperVGNS3VM(BaseGNS3VM):
|
||||
raise GNS3VMError("Could not find Hyper-V VM {}".format(self.vmname))
|
||||
|
||||
if not self._is_running():
|
||||
log.info("Update GNS3 VM settings (CPU and RAM)")
|
||||
# set the number of vCPUs and amount of RAM
|
||||
self._set_vcpus_ram(self.vcpus, self.ram)
|
||||
if self.allocate_vcpus_ram:
|
||||
log.info("Update GNS3 VM settings (CPU and RAM)")
|
||||
# set the number of vCPUs and amount of RAM
|
||||
self._set_vcpus_ram(self.vcpus, self.ram)
|
||||
|
||||
# start the VM
|
||||
try:
|
||||
|
@ -15,8 +15,6 @@
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import asyncio
|
||||
|
||||
from .base_gns3_vm import BaseGNS3VM
|
||||
from .gns3_vm_error import GNS3VMError
|
||||
|
||||
|
@ -260,9 +260,12 @@ class VirtualBoxGNS3VM(BaseGNS3VM):
|
||||
log.info('"{}" state is {}'.format(self._vmname, vm_state))
|
||||
|
||||
if vm_state == "poweroff":
|
||||
log.info("Update GNS3 VM settings (CPU, RAM and Hardware Virtualization)")
|
||||
await self.set_vcpus(self.vcpus)
|
||||
await self.set_ram(self.ram)
|
||||
if self.allocate_vcpus_ram:
|
||||
log.info("Update GNS3 VM vCPUs and RAM settings")
|
||||
await self.set_vcpus(self.vcpus)
|
||||
await self.set_ram(self.ram)
|
||||
|
||||
log.info("Update GNS3 VM Hardware Virtualization setting")
|
||||
await self.enable_nested_hw_virt()
|
||||
|
||||
if vm_state in ("poweroff", "saved"):
|
||||
|
@ -148,9 +148,12 @@ class VMwareGNS3VM(BaseGNS3VM):
|
||||
except VMwareError as e:
|
||||
raise GNS3VMError("Could not list VMware VMs: {}".format(str(e)))
|
||||
if not running:
|
||||
log.info("Update GNS3 VM settings (CPU, RAM and Hardware Virtualization)")
|
||||
# set the number of vCPUs and amount of RAM
|
||||
await self._set_vcpus_ram(self.vcpus, self.ram)
|
||||
if self.allocate_vcpus_ram:
|
||||
log.info("Update GNS3 VM vCPUs and RAM settings")
|
||||
await self._set_vcpus_ram(self.vcpus, self.ram)
|
||||
|
||||
log.info("Update GNS3 VM Hardware Virtualization setting")
|
||||
await self._set_extra_options()
|
||||
|
||||
# start the VM
|
||||
|
@ -174,6 +174,7 @@ class Project:
|
||||
self._links = {}
|
||||
self._drawings = {}
|
||||
self._snapshots = {}
|
||||
self._computes = []
|
||||
|
||||
# List the available snapshots
|
||||
snapshot_dir = os.path.join(self.path, "snapshots")
|
||||
@ -564,6 +565,9 @@ class Project:
|
||||
if node_id in self._nodes:
|
||||
return self._nodes[node_id]
|
||||
|
||||
if compute.id not in self._computes:
|
||||
self._computes.append(compute.id)
|
||||
|
||||
if node_type == "iou":
|
||||
async with self._iou_id_lock:
|
||||
# wait for a IOU node to be completely created before adding a new one
|
||||
@ -571,10 +575,10 @@ class Project:
|
||||
# to generate MAC addresses) when creating multiple IOU node at the same time
|
||||
if "properties" in kwargs.keys():
|
||||
# allocate a new application id for nodes loaded from the project
|
||||
kwargs.get("properties")["application_id"] = get_next_application_id(self._controller.projects, compute)
|
||||
kwargs.get("properties")["application_id"] = get_next_application_id(self._controller.projects, self._computes)
|
||||
elif "application_id" not in kwargs.keys() and not kwargs.get("properties"):
|
||||
# allocate a new application id for nodes added to the project
|
||||
kwargs["application_id"] = get_next_application_id(self._controller.projects, compute)
|
||||
kwargs["application_id"] = get_next_application_id(self._controller.projects, self._computes)
|
||||
node = await self._create_node(compute, name, node_id, node_type, **kwargs)
|
||||
else:
|
||||
node = await self._create_node(compute, name, node_id, node_type, **kwargs)
|
||||
@ -604,6 +608,8 @@ class Project:
|
||||
self.remove_allocated_node_name(node.name)
|
||||
del self._nodes[node.id]
|
||||
await node.destroy()
|
||||
# refresh the compute IDs list
|
||||
self._computes = [n.compute.id for n in self.nodes.values()]
|
||||
self.dump()
|
||||
self.emit_notification("node.deleted", node.__json__())
|
||||
|
||||
@ -931,6 +937,14 @@ class Project:
|
||||
topology = project_data["topology"]
|
||||
for compute in topology.get("computes", []):
|
||||
await self.controller.add_compute(**compute)
|
||||
|
||||
# Get all compute used in the project
|
||||
# used to allocate application IDs for IOU nodes.
|
||||
for node in topology.get("nodes", []):
|
||||
compute_id = node.get("compute_id")
|
||||
if compute_id not in self._computes:
|
||||
self._computes.append(compute_id)
|
||||
|
||||
for node in topology.get("nodes", []):
|
||||
compute = self.controller.get_compute(node.pop("compute_id"))
|
||||
name = node.pop("name")
|
||||
|
@ -58,7 +58,7 @@ class CrashReport:
|
||||
Report crash to a third party service
|
||||
"""
|
||||
|
||||
DSN = "https://c0b6ce011d024391831923745a47c33f:459ea5884d3944f092b02e4183cb6d52@o19455.ingest.sentry.io/38482"
|
||||
DSN = "https://026410fd151843438d078e604f2e4455:1792bf69988342c7b44f8a69ae0cad6f@o19455.ingest.sentry.io/38482"
|
||||
_instance = None
|
||||
|
||||
def __init__(self):
|
||||
|
@ -51,6 +51,7 @@ class GNS3VM(BaseModel):
|
||||
when_exit: Optional[WhenExit] = Field(None, description="Action when the GNS3 VM exits")
|
||||
headless: Optional[bool] = Field(None, description="Start the GNS3 VM GUI or not")
|
||||
engine: Optional[Engine] = Field(None, description="The engine to use for the GNS3 VM")
|
||||
allocate_vcpus_ram: Optional[bool] = Field(None, description="Allocate vCPUS and RAM settings")
|
||||
vcpus: Optional[int] = Field(None, description="Number of CPUs to allocate for the GNS3 VM")
|
||||
ram: Optional[int] = Field(None, description="Amount of memory to allocate for the GNS3 VM")
|
||||
port: Optional[int] = Field(None, gt=0, le=65535)
|
||||
|
@ -418,31 +418,6 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
|
||||
|
||||
angular2-hotkeys
|
||||
MIT
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2016 Nick Richardson
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
|
||||
|
||||
angular2-indexeddb
|
||||
MIT
|
||||
The MIT License (MIT)
|
||||
|
@ -48,5 +48,5 @@
|
||||
|
||||
gtag('config', 'G-5D6FZL9923');
|
||||
</script>
|
||||
<script src="runtime.acf0dec4155e77772545.js" defer></script><script src="polyfills-es5.81e70f503de320d59b44.js" nomodule defer></script><script src="polyfills.7ae454d57e44d75e5d10.js" defer></script><script src="main.b8ab802a67c1c69cf879.js" defer></script></body>
|
||||
<script src="runtime.acf0dec4155e77772545.js" defer></script><script src="polyfills-es5.81e70f503de320d59b44.js" nomodule defer></script><script src="polyfills.7ae454d57e44d75e5d10.js" defer></script><script src="main.8367ffc0bf45ea7cf3c7.js" defer></script></body>
|
||||
</html>
|
||||
|
1
gns3server/static/web-ui/main.8367ffc0bf45ea7cf3c7.js
Normal file
1
gns3server/static/web-ui/main.8367ffc0bf45ea7cf3c7.js
Normal file
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@ -21,26 +21,27 @@ import logging
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
|
||||
def get_next_application_id(projects, compute):
|
||||
def get_next_application_id(projects, computes):
|
||||
"""
|
||||
Calculates free application_id from given nodes
|
||||
|
||||
:param projects: all projects managed by controller
|
||||
:param compute: Compute instance
|
||||
:param computes: all computes used by the project
|
||||
:raises HTTPConflict when exceeds number
|
||||
:return: integer first free id
|
||||
"""
|
||||
|
||||
nodes = []
|
||||
|
||||
# look for application id for in all nodes across all opened projects that share the same compute
|
||||
# look for application id for in all nodes across all opened projects that share the same computes
|
||||
for project in projects.values():
|
||||
if project.status == "opened" and compute in project.computes:
|
||||
if project.status == "opened":
|
||||
nodes.extend(list(project.nodes.values()))
|
||||
|
||||
used = set([n.properties["application_id"] for n in nodes if n.node_type == "iou"])
|
||||
used = set([n.properties["application_id"] for n in nodes if n.node_type == "iou" and n.compute.id in computes])
|
||||
pool = set(range(1, 512))
|
||||
try:
|
||||
return (pool - used).pop()
|
||||
application_id = (pool - used).pop()
|
||||
return application_id
|
||||
except KeyError:
|
||||
raise ComputeError("Cannot create a new IOU node (limit of 512 nodes across all opened projects using compute {} reached".format(compute.name))
|
||||
raise ComputeError(text="Cannot create a new IOU node (limit of 512 nodes across all opened projects using the same computes)")
|
||||
|
0
gns3server/web/web_server.py
Normal file
0
gns3server/web/web_server.py
Normal file
@ -260,7 +260,7 @@ Conflicts=shutdown.target
|
||||
User=gns3
|
||||
Group=gns3
|
||||
PermissionsStartOnly=true
|
||||
Environment="PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
|
||||
EnvironmentFile=/etc/environment
|
||||
ExecStartPre=/bin/mkdir -p /var/log/gns3 /var/run/gns3
|
||||
ExecStartPre=/bin/chown -R gns3:gns3 /var/log/gns3 /var/run/gns3
|
||||
ExecStart=/usr/bin/gns3server --log /var/log/gns3/gns3.log
|
||||
|
Loading…
Reference in New Issue
Block a user