mirror of
https://github.com/GNS3/gns3-server
synced 2024-11-30 20:28:08 +00:00
Use Dynamips, IOU and VPCS identifiers to correctly load a topology.
This commit is contained in:
parent
f9ee38dd55
commit
cb763e0926
@ -176,7 +176,11 @@ class JSONRPCWebSocket(tornado.websocket.WebSocketHandler):
|
|||||||
Invoked when the WebSocket is closed.
|
Invoked when the WebSocket is closed.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
log.info("Websocket client {} disconnected".format(self.session_id))
|
try:
|
||||||
|
log.info("Websocket client {} disconnected".format(self.session_id))
|
||||||
|
except RuntimeError:
|
||||||
|
# to ignore logging exception: RuntimeError: reentrant call inside <_io.BufferedWriter name='<stderr>'>
|
||||||
|
pass
|
||||||
self.clients.remove(self)
|
self.clients.remove(self)
|
||||||
|
|
||||||
# Reset the modules if there are no clients anymore
|
# Reset the modules if there are no clients anymore
|
||||||
|
@ -132,9 +132,8 @@ class VM(object):
|
|||||||
image = request["image"]
|
image = request["image"]
|
||||||
ram = request["ram"]
|
ram = request["ram"]
|
||||||
hypervisor = None
|
hypervisor = None
|
||||||
chassis = None
|
chassis = request.get("chassis")
|
||||||
if "chassis" in request:
|
router_id = request.get("router_id")
|
||||||
chassis = request["chassis"]
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
|
|
||||||
@ -147,9 +146,9 @@ class VM(object):
|
|||||||
hypervisor = self._hypervisor_manager.allocate_hypervisor_for_router(image, ram)
|
hypervisor = self._hypervisor_manager.allocate_hypervisor_for_router(image, ram)
|
||||||
|
|
||||||
if chassis:
|
if chassis:
|
||||||
router = PLATFORMS[platform](hypervisor, name, chassis=chassis)
|
router = PLATFORMS[platform](hypervisor, name, router_id, chassis=chassis)
|
||||||
else:
|
else:
|
||||||
router = PLATFORMS[platform](hypervisor, name)
|
router = PLATFORMS[platform](hypervisor, name, router_id)
|
||||||
router.ram = ram
|
router.ram = ram
|
||||||
router.image = image
|
router.image = image
|
||||||
router.sparsemem = self._hypervisor_manager.sparse_memory_support
|
router.sparsemem = self._hypervisor_manager.sparse_memory_support
|
||||||
|
@ -34,13 +34,14 @@ class C1700(Router):
|
|||||||
|
|
||||||
:param hypervisor: Dynamips hypervisor instance
|
:param hypervisor: Dynamips hypervisor instance
|
||||||
:param name: name for this router
|
:param name: name for this router
|
||||||
|
:param router_id: router instance ID
|
||||||
:param chassis: chassis for this router:
|
:param chassis: chassis for this router:
|
||||||
1720, 1721, 1750, 1751 or 1760 (default = 1720).
|
1720, 1721, 1750, 1751 or 1760 (default = 1720).
|
||||||
1710 is not supported.
|
1710 is not supported.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, hypervisor, name, chassis="1720"):
|
def __init__(self, hypervisor, name, router_id=None, chassis="1720"):
|
||||||
Router.__init__(self, hypervisor, name, platform="c1700")
|
Router.__init__(self, hypervisor, name, router_id, platform="c1700")
|
||||||
|
|
||||||
# Set default values for this platform
|
# Set default values for this platform
|
||||||
self._ram = 64
|
self._ram = 64
|
||||||
|
@ -36,6 +36,7 @@ class C2600(Router):
|
|||||||
|
|
||||||
:param hypervisor: Dynamips hypervisor instance
|
:param hypervisor: Dynamips hypervisor instance
|
||||||
:param name: name for this router
|
:param name: name for this router
|
||||||
|
:param router_id: router instance ID
|
||||||
:param chassis: chassis for this router:
|
:param chassis: chassis for this router:
|
||||||
2610, 2611, 2620, 2621, 2610XM, 2611XM
|
2610, 2611, 2620, 2621, 2610XM, 2611XM
|
||||||
2620XM, 2621XM, 2650XM or 2651XM (default = 2610).
|
2620XM, 2621XM, 2650XM or 2651XM (default = 2610).
|
||||||
@ -54,8 +55,8 @@ class C2600(Router):
|
|||||||
"2650XM": C2600_MB_1FE,
|
"2650XM": C2600_MB_1FE,
|
||||||
"2651XM": C2600_MB_2FE}
|
"2651XM": C2600_MB_2FE}
|
||||||
|
|
||||||
def __init__(self, hypervisor, name, chassis="2610"):
|
def __init__(self, hypervisor, name, router_id=None, chassis="2610"):
|
||||||
Router.__init__(self, hypervisor, name, platform="c2600")
|
Router.__init__(self, hypervisor, name, router_id, platform="c2600")
|
||||||
|
|
||||||
# Set default values for this platform
|
# Set default values for this platform
|
||||||
self._ram = 64
|
self._ram = 64
|
||||||
|
@ -33,10 +33,11 @@ class C2691(Router):
|
|||||||
|
|
||||||
:param hypervisor: Dynamips hypervisor instance
|
:param hypervisor: Dynamips hypervisor instance
|
||||||
:param name: name for this router
|
:param name: name for this router
|
||||||
|
:param router_id: router instance ID
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, hypervisor, name):
|
def __init__(self, hypervisor, name, router_id=None):
|
||||||
Router.__init__(self, hypervisor, name, platform="c2691")
|
Router.__init__(self, hypervisor, name, router_id, platform="c2691")
|
||||||
|
|
||||||
# Set default values for this platform
|
# Set default values for this platform
|
||||||
self._ram = 128
|
self._ram = 128
|
||||||
|
@ -33,12 +33,13 @@ class C3600(Router):
|
|||||||
|
|
||||||
:param hypervisor: Dynamips hypervisor instance
|
:param hypervisor: Dynamips hypervisor instance
|
||||||
:param name: name for this router
|
:param name: name for this router
|
||||||
|
:param router_id: router instance ID
|
||||||
:param chassis: chassis for this router:
|
:param chassis: chassis for this router:
|
||||||
3620, 3640 or 3660 (default = 3640).
|
3620, 3640 or 3660 (default = 3640).
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, hypervisor, name, chassis="3640"):
|
def __init__(self, hypervisor, name, router_id=None, chassis="3640"):
|
||||||
Router.__init__(self, hypervisor, name, platform="c3600")
|
Router.__init__(self, hypervisor, name, router_id, platform="c3600")
|
||||||
|
|
||||||
# Set default values for this platform
|
# Set default values for this platform
|
||||||
self._ram = 128
|
self._ram = 128
|
||||||
|
@ -33,10 +33,11 @@ class C3725(Router):
|
|||||||
|
|
||||||
:param hypervisor: Dynamips hypervisor instance
|
:param hypervisor: Dynamips hypervisor instance
|
||||||
:param name: name for this router
|
:param name: name for this router
|
||||||
|
:param router_id: router instance ID
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, hypervisor, name):
|
def __init__(self, hypervisor, name, router_id=None):
|
||||||
Router.__init__(self, hypervisor, name, platform="c3725")
|
Router.__init__(self, hypervisor, name, router_id, platform="c3725")
|
||||||
|
|
||||||
# Set default values for this platform
|
# Set default values for this platform
|
||||||
self._ram = 128
|
self._ram = 128
|
||||||
|
@ -33,10 +33,11 @@ class C3745(Router):
|
|||||||
|
|
||||||
:param hypervisor: Dynamips hypervisor instance
|
:param hypervisor: Dynamips hypervisor instance
|
||||||
:param name: name for this router
|
:param name: name for this router
|
||||||
|
:param router_id: router instance ID
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, hypervisor, name):
|
def __init__(self, hypervisor, name, router_id=None):
|
||||||
Router.__init__(self, hypervisor, name, platform="c3745")
|
Router.__init__(self, hypervisor, name, router_id, platform="c3745")
|
||||||
|
|
||||||
# Set default values for this platform
|
# Set default values for this platform
|
||||||
self._ram = 128
|
self._ram = 128
|
||||||
|
@ -35,11 +35,12 @@ class C7200(Router):
|
|||||||
|
|
||||||
:param hypervisor: Dynamips hypervisor instance
|
:param hypervisor: Dynamips hypervisor instance
|
||||||
:param name: name for this router
|
:param name: name for this router
|
||||||
|
:param router_id: router instance ID
|
||||||
:param npe: default NPE
|
:param npe: default NPE
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, hypervisor, name, npe="npe-400"):
|
def __init__(self, hypervisor, name, router_id=None, npe="npe-400"):
|
||||||
Router.__init__(self, hypervisor, name, platform="c7200")
|
Router.__init__(self, hypervisor, name, router_id, platform="c7200")
|
||||||
|
|
||||||
# Set default values for this platform
|
# Set default values for this platform
|
||||||
self._ram = 256
|
self._ram = 256
|
||||||
|
@ -37,6 +37,7 @@ class Router(object):
|
|||||||
|
|
||||||
:param hypervisor: Dynamips hypervisor instance
|
:param hypervisor: Dynamips hypervisor instance
|
||||||
:param name: name for this router
|
:param name: name for this router
|
||||||
|
:param router_id: router instance ID
|
||||||
:param platform: c7200, c3745, c3725, c3600, c2691, c2600 or c1700
|
:param platform: c7200, c3745, c3725, c3600, c2691, c2600 or c1700
|
||||||
:param ghost_flag: used when creating a ghost IOS.
|
:param ghost_flag: used when creating a ghost IOS.
|
||||||
"""
|
"""
|
||||||
@ -49,20 +50,26 @@ class Router(object):
|
|||||||
2: "running",
|
2: "running",
|
||||||
3: "suspended"}
|
3: "suspended"}
|
||||||
|
|
||||||
def __init__(self, hypervisor, name, platform="c7200", ghost_flag=False):
|
def __init__(self, hypervisor, name, router_id=None, platform="c7200", ghost_flag=False):
|
||||||
|
|
||||||
if not ghost_flag:
|
if not ghost_flag:
|
||||||
|
|
||||||
# find an instance identifier (0 < id <= 4096)
|
if not router_id:
|
||||||
self._id = 0
|
# find an instance identifier if none is provided (0 < id <= 4096)
|
||||||
for identifier in range(1, 4097):
|
self._id = 0
|
||||||
if identifier not in self._instances:
|
for identifier in range(1, 4097):
|
||||||
self._id = identifier
|
if identifier not in self._instances:
|
||||||
self._instances.append(self._id)
|
self._id = identifier
|
||||||
break
|
self._instances.append(self._id)
|
||||||
|
break
|
||||||
|
|
||||||
if self._id == 0:
|
if self._id == 0:
|
||||||
raise DynamipsError("Maximum number of instances reached")
|
raise DynamipsError("Maximum number of instances reached")
|
||||||
|
else:
|
||||||
|
if router_id in self._instances:
|
||||||
|
raise DynamipsError("Router identifier {} is already used by another router".format(router_id))
|
||||||
|
self._id = router_id
|
||||||
|
self._instances.append(self._id)
|
||||||
|
|
||||||
else:
|
else:
|
||||||
log.info("creating a new ghost IOS file")
|
log.info("creating a new ghost IOS file")
|
||||||
|
@ -25,6 +25,10 @@ VM_CREATE_SCHEMA = {
|
|||||||
"type": "string",
|
"type": "string",
|
||||||
"minLength": 1,
|
"minLength": 1,
|
||||||
},
|
},
|
||||||
|
"router_id": {
|
||||||
|
"description": "VM/router instance ID",
|
||||||
|
"type": "integer"
|
||||||
|
},
|
||||||
"platform": {
|
"platform": {
|
||||||
"description": "router platform",
|
"description": "router platform",
|
||||||
"type": "string",
|
"type": "string",
|
||||||
|
@ -290,12 +290,14 @@ class IOU(IModule):
|
|||||||
name = request["name"]
|
name = request["name"]
|
||||||
iou_path = request["path"]
|
iou_path = request["path"]
|
||||||
console = request.get("console")
|
console = request.get("console")
|
||||||
|
iou_id = request.get("iou_id")
|
||||||
|
|
||||||
try:
|
try:
|
||||||
iou_instance = IOUDevice(name,
|
iou_instance = IOUDevice(name,
|
||||||
iou_path,
|
iou_path,
|
||||||
self._working_dir,
|
self._working_dir,
|
||||||
self._host,
|
self._host,
|
||||||
|
iou_id,
|
||||||
console,
|
console,
|
||||||
self._console_start_port_range,
|
self._console_start_port_range,
|
||||||
self._console_end_port_range)
|
self._console_end_port_range)
|
||||||
|
@ -46,10 +46,11 @@ class IOUDevice(object):
|
|||||||
"""
|
"""
|
||||||
IOU device implementation.
|
IOU device implementation.
|
||||||
|
|
||||||
|
:param name: name of this IOU device
|
||||||
:param path: path to IOU executable
|
:param path: path to IOU executable
|
||||||
:param working_dir: path to a working directory
|
:param working_dir: path to a working directory
|
||||||
:param host: host/address to bind for console and UDP connections
|
:param host: host/address to bind for console and UDP connections
|
||||||
:param name: name of this IOU device
|
:param iou_id: IOU instance ID
|
||||||
:param console: TCP console port
|
:param console: TCP console port
|
||||||
:param console_start_port_range: TCP console port range start
|
:param console_start_port_range: TCP console port range start
|
||||||
:param console_end_port_range: TCP console port range end
|
:param console_end_port_range: TCP console port range end
|
||||||
@ -63,20 +64,27 @@ class IOUDevice(object):
|
|||||||
path,
|
path,
|
||||||
working_dir,
|
working_dir,
|
||||||
host="127.0.0.1",
|
host="127.0.0.1",
|
||||||
|
iou_id = None,
|
||||||
console=None,
|
console=None,
|
||||||
console_start_port_range=4001,
|
console_start_port_range=4001,
|
||||||
console_end_port_range=4512):
|
console_end_port_range=4512):
|
||||||
|
|
||||||
# find an instance identifier (0 < id <= 512)
|
if not iou_id:
|
||||||
self._id = 0
|
# find an instance identifier if none is provided (0 < id <= 512)
|
||||||
for identifier in range(1, 513):
|
self._id = 0
|
||||||
if identifier not in self._instances:
|
for identifier in range(1, 513):
|
||||||
self._id = identifier
|
if identifier not in self._instances:
|
||||||
self._instances.append(self._id)
|
self._id = identifier
|
||||||
break
|
self._instances.append(self._id)
|
||||||
|
break
|
||||||
|
|
||||||
if self._id == 0:
|
if self._id == 0:
|
||||||
raise IOUError("Maximum number of IOU instances reached")
|
raise IOUError("Maximum number of IOU instances reached")
|
||||||
|
else:
|
||||||
|
if iou_id in self._instances:
|
||||||
|
raise IOUError("IOU identifier {} is already used by another IOU device".format(iou_id))
|
||||||
|
self._id = iou_id
|
||||||
|
self._instances.append(self._id)
|
||||||
|
|
||||||
self._name = name
|
self._name = name
|
||||||
self._path = path
|
self._path = path
|
||||||
@ -106,8 +114,13 @@ class IOUDevice(object):
|
|||||||
self._ram = 256 # Megabytes
|
self._ram = 256 # Megabytes
|
||||||
self._l1_keepalives = False # used to overcome the always-up Ethernet interfaces (not supported by all IOSes).
|
self._l1_keepalives = False # used to overcome the always-up Ethernet interfaces (not supported by all IOSes).
|
||||||
|
|
||||||
|
working_dir_path = os.path.join(working_dir, "iou", "device-{}".format(self._id))
|
||||||
|
|
||||||
|
if iou_id and not os.path.isdir(working_dir_path):
|
||||||
|
raise IOUError("Working directory {} doesn't exist".format(working_dir_path))
|
||||||
|
|
||||||
# create the device own working directory
|
# create the device own working directory
|
||||||
self.working_dir = os.path.join(working_dir, "iou", "{}".format(self._name))
|
self.working_dir = working_dir_path
|
||||||
|
|
||||||
if not self._console:
|
if not self._console:
|
||||||
# allocate a console port
|
# allocate a console port
|
||||||
|
@ -26,6 +26,10 @@ IOU_CREATE_SCHEMA = {
|
|||||||
"type": "string",
|
"type": "string",
|
||||||
"minLength": 1,
|
"minLength": 1,
|
||||||
},
|
},
|
||||||
|
"iou_id": {
|
||||||
|
"description": "IOU device instance ID",
|
||||||
|
"type": "integer"
|
||||||
|
},
|
||||||
"console": {
|
"console": {
|
||||||
"description": "console TCP port",
|
"description": "console TCP port",
|
||||||
"minimum": 1,
|
"minimum": 1,
|
||||||
|
@ -226,6 +226,7 @@ class VPCS(IModule):
|
|||||||
|
|
||||||
name = request["name"]
|
name = request["name"]
|
||||||
console = request.get("console")
|
console = request.get("console")
|
||||||
|
vpcs_id = request.get("vpcs_id")
|
||||||
|
|
||||||
try:
|
try:
|
||||||
|
|
||||||
@ -236,6 +237,7 @@ class VPCS(IModule):
|
|||||||
self._vpcs,
|
self._vpcs,
|
||||||
self._working_dir,
|
self._working_dir,
|
||||||
self._host,
|
self._host,
|
||||||
|
vpcs_id,
|
||||||
console,
|
console,
|
||||||
self._console_start_port_range,
|
self._console_start_port_range,
|
||||||
self._console_end_port_range)
|
self._console_end_port_range)
|
||||||
|
@ -26,6 +26,10 @@ VPCS_CREATE_SCHEMA = {
|
|||||||
"type": "string",
|
"type": "string",
|
||||||
"minLength": 1,
|
"minLength": 1,
|
||||||
},
|
},
|
||||||
|
"vpcs_id": {
|
||||||
|
"description": "VPCS device instance ID",
|
||||||
|
"type": "integer"
|
||||||
|
},
|
||||||
"console": {
|
"console": {
|
||||||
"description": "console TCP port",
|
"description": "console TCP port",
|
||||||
"minimum": 1,
|
"minimum": 1,
|
||||||
|
@ -40,10 +40,11 @@ class VPCSDevice(object):
|
|||||||
"""
|
"""
|
||||||
VPCS device implementation.
|
VPCS device implementation.
|
||||||
|
|
||||||
|
:param name: name of this VPCS device
|
||||||
:param path: path to VPCS executable
|
:param path: path to VPCS executable
|
||||||
:param working_dir: path to a working directory
|
:param working_dir: path to a working directory
|
||||||
:param host: host/address to bind for console and UDP connections
|
:param host: host/address to bind for console and UDP connections
|
||||||
:param name: name of this VPCS device
|
:param vpcs_id: VPCS instance ID
|
||||||
:param console: TCP console port
|
:param console: TCP console port
|
||||||
:param console_start_port_range: TCP console port range start
|
:param console_start_port_range: TCP console port range start
|
||||||
:param console_end_port_range: TCP console port range end
|
:param console_end_port_range: TCP console port range end
|
||||||
@ -57,22 +58,30 @@ class VPCSDevice(object):
|
|||||||
path,
|
path,
|
||||||
working_dir,
|
working_dir,
|
||||||
host="127.0.0.1",
|
host="127.0.0.1",
|
||||||
|
vpcs_id=None,
|
||||||
console=None,
|
console=None,
|
||||||
console_start_port_range=4512,
|
console_start_port_range=4512,
|
||||||
console_end_port_range=5000):
|
console_end_port_range=5000):
|
||||||
|
|
||||||
# find an instance identifier (1 <= id <= 255)
|
|
||||||
# This 255 limit is due to a restriction on the number of possible
|
|
||||||
# MAC addresses given in VPCS using the -m option
|
|
||||||
self._id = 0
|
|
||||||
for identifier in range(1, 256):
|
|
||||||
if identifier not in self._instances:
|
|
||||||
self._id = identifier
|
|
||||||
self._instances.append(self._id)
|
|
||||||
break
|
|
||||||
|
|
||||||
if self._id == 0:
|
if not vpcs_id:
|
||||||
raise VPCSError("Maximum number of VPCS instances reached")
|
# find an instance identifier is none is provided (1 <= id <= 255)
|
||||||
|
# This 255 limit is due to a restriction on the number of possible
|
||||||
|
# MAC addresses given in VPCS using the -m option
|
||||||
|
self._id = 0
|
||||||
|
for identifier in range(1, 256):
|
||||||
|
if identifier not in self._instances:
|
||||||
|
self._id = identifier
|
||||||
|
self._instances.append(self._id)
|
||||||
|
break
|
||||||
|
|
||||||
|
if self._id == 0:
|
||||||
|
raise VPCSError("Maximum number of VPCS instances reached")
|
||||||
|
else:
|
||||||
|
if vpcs_id in self._instances:
|
||||||
|
raise VPCSError("VPCS identifier {} is already used by another VPCS device".format(vpcs_id))
|
||||||
|
self._id = vpcs_id
|
||||||
|
self._instances.append(self._id)
|
||||||
|
|
||||||
self._name = name
|
self._name = name
|
||||||
self._path = path
|
self._path = path
|
||||||
@ -91,8 +100,13 @@ class VPCSDevice(object):
|
|||||||
self._script_file = ""
|
self._script_file = ""
|
||||||
self._ethernet_adapter = EthernetAdapter() # one adapter with 1 Ethernet interface
|
self._ethernet_adapter = EthernetAdapter() # one adapter with 1 Ethernet interface
|
||||||
|
|
||||||
|
working_dir_path = os.path.join(working_dir, "vpcs", "pc-{}".format(self._id))
|
||||||
|
|
||||||
|
if vpcs_id and not os.path.isdir(working_dir_path):
|
||||||
|
raise VPCSError("Working directory {} doesn't exist".format(working_dir_path))
|
||||||
|
|
||||||
# create the device own working directory
|
# create the device own working directory
|
||||||
self.working_dir = os.path.join(working_dir, "vpcs", "{}".format(name))
|
self.working_dir = working_dir_path
|
||||||
|
|
||||||
if not self._console:
|
if not self._console:
|
||||||
# allocate a console port
|
# allocate a console port
|
||||||
|
@ -23,5 +23,5 @@
|
|||||||
# or negative for a release candidate or beta (after the base version
|
# or negative for a release candidate or beta (after the base version
|
||||||
# number has been incremented)
|
# number has been incremented)
|
||||||
|
|
||||||
__version__ = "1.0a7.dev1"
|
__version__ = "1.0a7.dev2"
|
||||||
__version_info__ = (1, 0, 0, -99)
|
__version_info__ = (1, 0, 0, -99)
|
||||||
|
Loading…
Reference in New Issue
Block a user