New Dynamips integration part 3

This commit is contained in:
Jeremy committed 2015-02-11 19:21:34 -07:00
1 parent 37945585b9
commit 79a57ca420
51 files changed
+1257 -2386

No files matched your search

+136 -382
View File
@@ -19,81 +19,18 @@
Dynamips server module.
"""
import aiohttp
import sys
import os
import base64
import tempfile
import shutil
import glob
import socket
from gns3server.config import Config
# from .hypervisor import Hypervisor
# from .hypervisor_manager import HypervisorManager
# from .dynamips_error import DynamipsError
#
# # Nodes
# from .nodes.router import Router
# from .nodes.c1700 import C1700
# from .nodes.c2600 import C2600
# from .nodes.c2691 import C2691
# from .nodes.c3600 import C3600
# from .nodes.c3725 import C3725
# from .nodes.c3745 import C3745
# from .nodes.c7200 import C7200
# from .nodes.bridge import Bridge
# from .nodes.ethernet_switch import EthernetSwitch
# from .nodes.atm_switch import ATMSwitch
# from .nodes.atm_bridge import ATMBridge
# from .nodes.frame_relay_switch import FrameRelaySwitch
# from .nodes.hub import Hub
#
# # Adapters
# from .adapters.c7200_io_2fe import C7200_IO_2FE
# from .adapters.c7200_io_fe import C7200_IO_FE
# from .adapters.c7200_io_ge_e import C7200_IO_GE_E
# from .adapters.nm_16esw import NM_16ESW
# from .adapters.nm_1e import NM_1E
# from .adapters.nm_1fe_tx import NM_1FE_TX
# from .adapters.nm_4e import NM_4E
# from .adapters.nm_4t import NM_4T
# from .adapters.pa_2fe_tx import PA_2FE_TX
# from .adapters.pa_4e import PA_4E
# from .adapters.pa_4t import PA_4T
# from .adapters.pa_8e import PA_8E
# from .adapters.pa_8t import PA_8T
# from .adapters.pa_a1 import PA_A1
# from .adapters.pa_fe_tx import PA_FE_TX
# from .adapters.pa_ge import PA_GE
# from .adapters.pa_pos_oc3 import PA_POS_OC3
# from .adapters.wic_1t import WIC_1T
# from .adapters.wic_2t import WIC_2T
# from .adapters.wic_1enet import WIC_1ENET
#
# # NIOs
# from .nios.nio_udp import NIO_UDP
# from .nios.nio_udp_auto import NIO_UDP_auto
# from .nios.nio_unix import NIO_UNIX
# from .nios.nio_vde import NIO_VDE
# from .nios.nio_tap import NIO_TAP
# from .nios.nio_generic_ethernet import NIO_GenericEthernet
# from .nios.nio_linux_ethernet import NIO_LinuxEthernet
# from .nios.nio_fifo import NIO_FIFO
# from .nios.nio_mcast import NIO_Mcast
# from .nios.nio_null import NIO_Null
#
# from .backends import vm
# from .backends import ethsw
# from .backends import ethhub
# from .backends import frsw
# from .backends import atmsw
import time
import asyncio
import logging
log = logging.getLogger(__name__)
from gns3server.utils.interfaces import get_windows_interfaces
from pkg_resources import parse_version
from ..base_manager import BaseManager
from .dynamips_error import DynamipsError
@@ -101,6 +38,18 @@ from .hypervisor import Hypervisor
from .nodes.router import Router
from .dynamips_vm import DynamipsVM
# NIOs
from .nios.nio_udp import NIOUDP
from .nios.nio_udp_auto import NIOUDPAuto
from .nios.nio_unix import NIOUNIX
from .nios.nio_vde import NIOVDE
from .nios.nio_tap import NIOTAP
from .nios.nio_generic_ethernet import NIOGenericEthernet
from .nios.nio_linux_ethernet import NIOLinuxEthernet
from .nios.nio_fifo import NIOFIFO
from .nios.nio_mcast import NIOMcast
from .nios.nio_null import NIONull
class Dynamips(BaseManager):
@@ -113,7 +62,35 @@ class Dynamips(BaseManager):
# FIXME: temporary
self._working_dir = "/tmp"
self._dynamips_path = "/usr/bin/dynamips"
@asyncio.coroutine
def unload(self):
yield from BaseManager.unload(self)
Router.reset()
# files = glob.glob(os.path.join(self._working_dir, "dynamips", "*.ghost"))
# files += glob.glob(os.path.join(self._working_dir, "dynamips", "*_lock"))
# files += glob.glob(os.path.join(self._working_dir, "dynamips", "ilt_*"))
# files += glob.glob(os.path.join(self._working_dir, "dynamips", "c[0-9][0-9][0-9][0-9]_*_rommon_vars"))
# files += glob.glob(os.path.join(self._working_dir, "dynamips", "c[0-9][0-9][0-9][0-9]_*_ssa"))
# for file in files:
# try:
# log.debug("deleting file {}".format(file))
# os.remove(file)
# except OSError as e:
# log.warn("could not delete file {}: {}".format(file, e))
# continue
@property
def dynamips_path(self):
"""
Returns the path to Dynamips.
:returns: path
"""
return self._dynamips_path
def find_dynamips(self):
@@ -168,6 +145,9 @@ class Dynamips(BaseManager):
:returns: the new hypervisor instance
"""
if not self._dynamips_path:
self.find_dynamips()
try:
# let the OS find an unused port for the Dynamips hypervisor
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as sock:
@@ -190,323 +170,97 @@ class Dynamips(BaseManager):
return hypervisor
def create_nio(self, executable, nio_settings):
"""
Creates a new NIO.
:param nio_settings: information to create the NIO
:returns: a NIO object
"""
nio = None
if nio_settings["type"] == "nio_udp":
lport = nio_settings["lport"]
rhost = nio_settings["rhost"]
rport = nio_settings["rport"]
try:
# TODO: handle IPv6
with socket.socket(socket.AF_INET, socket.SOCK_DGRAM) as sock:
sock.connect((rhost, rport))
except OSError as e:
raise aiohttp.web.HTTPInternalServerError(text="Could not create an UDP connection to {}:{}: {}".format(rhost, rport, e))
nio = NIOUDP(lport, rhost, rport)
elif nio_settings["type"] == "nio_tap":
tap_device = nio_settings["tap_device"]
if not self._has_privileged_access(executable):
raise aiohttp.web.HTTPForbidden(text="{} has no privileged access to {}.".format(executable, tap_device))
nio = NIOTAP(tap_device)
assert nio is not None
return nio
def create_nio(self, node, nio_settings):
"""
Creates a new NIO.
:param node: Dynamips node instance
:param nio_settings: information to create the NIO
:returns: a NIO object
"""
nio = None
if nio_settings["type"] == "nio_udp":
lport = nio_settings["lport"]
rhost = nio_settings["rhost"]
rport = nio_settings["rport"]
try:
#TODO: handle IPv6
with socket.socket(socket.AF_INET, socket.SOCK_DGRAM) as sock:
sock.connect((rhost, rport))
except OSError as e:
raise DynamipsError("Could not create an UDP connection to {}:{}: {}".format(rhost, rport, e))
# check if we have an allocated NIO UDP auto
nio = node.hypervisor.get_nio_udp_auto(lport)
if not nio:
# otherwise create an NIO UDP
nio = NIOUDP(node.hypervisor, lport, rhost, rport)
else:
nio.connect(rhost, rport)
elif nio_settings["type"] == "nio_generic_ethernet":
ethernet_device = nio_settings["ethernet_device"]
if sys.platform.startswith("win"):
# replace the interface name by the GUID on Windows
interfaces = get_windows_interfaces()
npf_interface = None
for interface in interfaces:
if interface["name"] == ethernet_device:
npf_interface = interface["id"]
if not npf_interface:
raise DynamipsError("Could not find interface {} on this host".format(ethernet_device))
else:
ethernet_device = npf_interface
nio = NIOGenericEthernet(node.hypervisor, ethernet_device)
elif nio_settings["type"] == "nio_linux_ethernet":
if sys.platform.startswith("win"):
raise DynamipsError("This NIO type is not supported on Windows")
ethernet_device = nio_settings["ethernet_device"]
nio = NIOLinuxEthernet(node.hypervisor, ethernet_device)
elif nio_settings["type"] == "nio_tap":
tap_device = nio_settings["tap_device"]
nio = NIOTAP(node.hypervisor, tap_device)
elif nio_settings["type"] == "nio_unix":
local_file = nio_settings["local_file"]
remote_file = nio_settings["remote_file"]
nio = NIOUNIX(node.hypervisor, local_file, remote_file)
elif nio_settings["type"] == "nio_vde":
control_file = nio_settings["control_file"]
local_file = nio_settings["local_file"]
nio = NIOVDE(node.hypervisor, control_file, local_file)
elif nio_settings["type"] == "nio_null":
nio = NIONull(node.hypervisor)
return nio
# class Dynamips(IModule):
# """
# Dynamips module.
#
# :param name: module name
# :param args: arguments for the module
# :param kwargs: named arguments for the module
# """
#
# def stop(self, signum=None):
# """
# Properly stops the module.
#
# :param signum: signal number (if called by the signal handler)
# """
#
# if not sys.platform.startswith("win32"):
# self._callback.stop()
#
# # automatically save configs for all router instances
# for router_id in self._routers:
# router = self._routers[router_id]
# try:
# router.save_configs()
# except DynamipsError:
# continue
#
# # stop all Dynamips hypervisors
# if self._hypervisor_manager:
# self._hypervisor_manager.stop_all_hypervisors()
#
# self.delete_dynamips_files()
# IModule.stop(self, signum) # this will stop the I/O loop
#
# def get_device_instance(self, device_id, instance_dict):
# """
# Returns a device instance.
#
# :param device_id: device identifier
# :param instance_dict: dictionary containing the instances
#
# :returns: device instance
# """
#
# if device_id not in instance_dict:
# log.debug("device ID {} doesn't exist".format(device_id), exc_info=1)
# self.send_custom_error("Device ID {} doesn't exist".format(device_id))
# return None
# return instance_dict[device_id]
#
# def delete_dynamips_files(self):
# """
# Deletes useless Dynamips files from the working directory
# """
#
# files = glob.glob(os.path.join(self._working_dir, "dynamips", "*.ghost"))
# files += glob.glob(os.path.join(self._working_dir, "dynamips", "*_lock"))
# files += glob.glob(os.path.join(self._working_dir, "dynamips", "ilt_*"))
# files += glob.glob(os.path.join(self._working_dir, "dynamips", "c[0-9][0-9][0-9][0-9]_*_rommon_vars"))
# files += glob.glob(os.path.join(self._working_dir, "dynamips", "c[0-9][0-9][0-9][0-9]_*_ssa"))
# for file in files:
# try:
# log.debug("deleting file {}".format(file))
# os.remove(file)
# except OSError as e:
# log.warn("could not delete file {}: {}".format(file, e))
# continue
#
# @IModule.route("dynamips.reset")
# def reset(self, request=None):
# """
# Resets the module (JSON-RPC notification).
#
# :param request: JSON request (not used)
# """
#
# # automatically save configs for all router instances
# for router_id in self._routers:
# router = self._routers[router_id]
# try:
# router.save_configs()
# except DynamipsError:
# continue
#
# # stop all Dynamips hypervisors
# if self._hypervisor_manager:
# self._hypervisor_manager.stop_all_hypervisors()
#
# # resets the instance counters
# Router.reset()
# EthernetSwitch.reset()
# Hub.reset()
# FrameRelaySwitch.reset()
# ATMSwitch.reset()
# NIO_UDP.reset()
# NIO_UDP_auto.reset()
# NIO_UNIX.reset()
# NIO_VDE.reset()
# NIO_TAP.reset()
# NIO_GenericEthernet.reset()
# NIO_LinuxEthernet.reset()
# NIO_FIFO.reset()
# NIO_Mcast.reset()
# NIO_Null.reset()
#
# self._routers.clear()
# self._ethernet_switches.clear()
# self._frame_relay_switches.clear()
# self._atm_switches.clear()
#
# self.delete_dynamips_files()
#
# self._hypervisor_manager = None
# self._working_dir = self._projects_dir
# log.info("dynamips module has been reset")
#
# def start_hypervisor_manager(self):
# """
# Starts the hypervisor manager.
# """
#
# # check if Dynamips path exists
# if not os.path.isfile(self._dynamips):
# raise DynamipsError("Dynamips executable {} doesn't exist".format(self._dynamips))
#
# # check if Dynamips is executable
# if not os.access(self._dynamips, os.X_OK):
# raise DynamipsError("Dynamips {} is not executable".format(self._dynamips))
#
# workdir = os.path.join(self._working_dir, "dynamips")
# try:
# os.makedirs(workdir)
# except FileExistsError:
# pass
# except OSError as e:
# raise DynamipsError("Could not create working directory {}".format(e))
#
# # check if the working directory is writable
# if not os.access(workdir, os.W_OK):
# raise DynamipsError("Cannot write to working directory {}".format(workdir))
#
# log.info("starting the hypervisor manager with Dynamips working directory set to '{}'".format(workdir))
# self._hypervisor_manager = HypervisorManager(self._dynamips, workdir, self._host, self._console_host)
#
# for name, value in self._hypervisor_manager_settings.items():
# if hasattr(self._hypervisor_manager, name) and getattr(self._hypervisor_manager, name) != value:
# setattr(self._hypervisor_manager, name, value)
#
# @IModule.route("dynamips.settings")
# def settings(self, request):
# """
# Set or update settings.
#
# Optional request parameters:
# - path (path to the Dynamips executable)
# - working_dir (path to a working directory)
# - project_name
#
# :param request: JSON request
# """
#
# if request is None:
# self.send_param_error()
# return
#
# log.debug("received request {}".format(request))
#
# #TODO: JSON schema validation
# if not self._hypervisor_manager:
#
# if "path" in request:
# self._dynamips = request.pop("path")
#
# if "working_dir" in request:
# self._working_dir = request.pop("working_dir")
# log.info("this server is local")
# else:
# self._working_dir = os.path.join(self._projects_dir, request["project_name"])
# log.info("this server is remote with working directory path to {}".format(self._working_dir))
#
# self._hypervisor_manager_settings = request
#
# else:
# if "project_name" in request:
# # for remote server
# new_working_dir = os.path.join(self._projects_dir, request["project_name"])
#
# if self._projects_dir != self._working_dir != new_working_dir:
#
# # trick to avoid file locks by Dynamips on Windows
# if sys.platform.startswith("win"):
# self._hypervisor_manager.working_dir = tempfile.gettempdir()
#
# if not os.path.isdir(new_working_dir):
# try:
# self.delete_dynamips_files()
# shutil.move(self._working_dir, new_working_dir)
# except OSError as e:
# log.error("could not move working directory from {} to {}: {}".format(self._working_dir,
# new_working_dir,
# e))
# return
#
# elif "working_dir" in request:
# # for local server
# new_working_dir = request.pop("working_dir")
#
# try:
# self._hypervisor_manager.working_dir = new_working_dir
# except DynamipsError as e:
# log.error("could not change working directory: {}".format(e))
# return
#
# self._working_dir = new_working_dir
#
# # apply settings to the hypervisor manager
# for name, value in request.items():
# if hasattr(self._hypervisor_manager, name) and getattr(self._hypervisor_manager, name) != value:
# setattr(self._hypervisor_manager, name, value)
#
# @IModule.route("dynamips.echo")
# def echo(self, request):
# """
# Echo end point for testing purposes.
#
# :param request: JSON request
# """
#
# if request is None:
# self.send_param_error()
# else:
# log.debug("received request {}".format(request))
# self.send_response(request)
#
# def create_nio(self, node, request):
# """
# Creates a new NIO.
#
# :param node: node requesting the NIO
# :param request: the original request with the
# necessary information to create the NIO
#
# :returns: a NIO object
# """
#
# nio = None
# if request["nio"]["type"] == "nio_udp":
# lport = request["nio"]["lport"]
# rhost = request["nio"]["rhost"]
# rport = request["nio"]["rport"]
# try:
# #TODO: handle IPv6
# with socket.socket(socket.AF_INET, socket.SOCK_DGRAM) as sock:
# sock.connect((rhost, rport))
# except OSError as e:
# raise DynamipsError("Could not create an UDP connection to {}:{}: {}".format(rhost, rport, e))
# # check if we have an allocated NIO UDP auto
# nio = node.hypervisor.get_nio_udp_auto(lport)
# if not nio:
# # otherwise create an NIO UDP
# nio = NIO_UDP(node.hypervisor, lport, rhost, rport)
# else:
# nio.connect(rhost, rport)
# elif request["nio"]["type"] == "nio_generic_ethernet":
# ethernet_device = request["nio"]["ethernet_device"]
# if sys.platform.startswith("win"):
# # replace the interface name by the GUID on Windows
# interfaces = get_windows_interfaces()
# npf_interface = None
# for interface in interfaces:
# if interface["name"] == ethernet_device:
# npf_interface = interface["id"]
# if not npf_interface:
# raise DynamipsError("Could not find interface {} on this host".format(ethernet_device))
# else:
# ethernet_device = npf_interface
# nio = NIO_GenericEthernet(node.hypervisor, ethernet_device)
# elif request["nio"]["type"] == "nio_linux_ethernet":
# if sys.platform.startswith("win"):
# raise DynamipsError("This NIO type is not supported on Windows")
# ethernet_device = request["nio"]["ethernet_device"]
# nio = NIO_LinuxEthernet(node.hypervisor, ethernet_device)
# elif request["nio"]["type"] == "nio_tap":
# tap_device = request["nio"]["tap_device"]
# nio = NIO_TAP(node.hypervisor, tap_device)
# elif request["nio"]["type"] == "nio_unix":
# local_file = request["nio"]["local_file"]
# remote_file = request["nio"]["remote_file"]
# nio = NIO_UNIX(node.hypervisor, local_file, remote_file)
# elif request["nio"]["type"] == "nio_vde":
# control_file = request["nio"]["control_file"]
# local_file = request["nio"]["local_file"]
# nio = NIO_VDE(node.hypervisor, control_file, local_file)
# elif request["nio"]["type"] == "nio_null":
# nio = NIO_Null(node.hypervisor)
# return nio
#
# def allocate_udp_port(self, node):
# """
# Allocates a UDP port in order to create an UDP NIO.
#
# :param node: the node that needs to allocate an UDP port
#
# :returns: dictionary with the allocated host/port info
# """
#
# port = node.hypervisor.allocate_udp_port()
# host = node.hypervisor.host
#
# log.info("{} [id={}] has allocated UDP port {} with host {}".format(node.name,
# node.id,
# port,
# host))
# response = {"lport": port}
# return response
#
# def set_ghost_ios(self, router):
# """
# Manages Ghost IOS support.
@@ -26,7 +26,7 @@ import logging
import asyncio
from .dynamips_error import DynamipsError
from .nios.nio_udp_auto import NIO_UDP_auto
from .nios.nio_udp_auto import NIOUDPAuto
log = logging.getLogger(__name__)
@@ -415,7 +415,7 @@ class DynamipsHypervisor:
"""
# use Dynamips's NIO UDP auto back-end.
nio = NIO_UDP_auto(self, self._host, self._udp_start_port_range, self._udp_end_port_range)
nio = NIOUDPAuto(self, self._host, self._udp_start_port_range, self._udp_end_port_range)
self._nio_udp_auto_instances[nio.lport] = nio
allocated_port = nio.lport
return allocated_port
+2 -2
View File
@@ -42,9 +42,9 @@ class DynamipsVM:
Factory to create an Router object based on the correct platform.
"""
def __new__(cls, name, vm_id, project, manager, platform, **kwargs):
def __new__(cls, name, vm_id, project, manager, dynamips_id, platform, **kwargs):
if platform not in PLATFORMS:
raise DynamipsError("Unknown router platform: {}".format(platform))
return PLATFORMS[platform](name, vm_id, project, manager, **kwargs)
return PLATFORMS[platform](name, vm_id, project, manager, dynamips_id, **kwargs)
+3 -3
View File
@@ -26,7 +26,7 @@ import logging
log = logging.getLogger(__name__)
class NIO_FIFO(NIO):
class NIOFIFO(NIO):
"""
Dynamips FIFO NIO.
@@ -40,8 +40,8 @@ class NIO_FIFO(NIO):
NIO.__init__(self, hypervisor)
# create an unique ID
self._id = NIO_FIFO._instance_count
NIO_FIFO._instance_count += 1
self._id = NIOFIFO._instance_count
NIOFIFO._instance_count += 1
self._name = 'nio_fifo' + str(self._id)
@classmethod
@@ -26,7 +26,7 @@ import logging
log = logging.getLogger(__name__)
class NIO_GenericEthernet(NIO):
class NIOGenericEthernet(NIO):
"""
Dynamips generic Ethernet NIO.
@@ -41,8 +41,8 @@ class NIO_GenericEthernet(NIO):
NIO.__init__(self, hypervisor)
# create an unique ID
self._id = NIO_GenericEthernet._instance_count
NIO_GenericEthernet._instance_count += 1
self._id = NIOGenericEthernet._instance_count
NIOGenericEthernet._instance_count += 1
self._name = 'nio_gen_eth' + str(self._id)
self._ethernet_device = ethernet_device
@@ -26,7 +26,7 @@ import logging
log = logging.getLogger(__name__)
class NIO_LinuxEthernet(NIO):
class NIOLinuxEthernet(NIO):
"""
Dynamips Linux Ethernet NIO.
@@ -41,8 +41,8 @@ class NIO_LinuxEthernet(NIO):
NIO.__init__(self, hypervisor)
# create an unique ID
self._id = NIO_LinuxEthernet._instance_count
NIO_LinuxEthernet._instance_count += 1
self._id = NIOLinuxEthernet._instance_count
NIOLinuxEthernet._instance_count += 1
self._name = 'nio_linux_eth' + str(self._id)
self._ethernet_device = ethernet_device
@@ -26,7 +26,7 @@ import logging
log = logging.getLogger(__name__)
class NIO_Mcast(NIO):
class NIOMcast(NIO):
"""
Dynamips Linux Ethernet NIO.
@@ -42,8 +42,8 @@ class NIO_Mcast(NIO):
NIO.__init__(self, hypervisor)
# create an unique ID
self._id = NIO_Mcast._instance_count
NIO_Mcast._instance_count += 1
self._id = NIOMcast._instance_count
NIOMcast._instance_count += 1
self._name = 'nio_mcast' + str(self._id)
self._group = group
self._port = port
+3 -3
View File
@@ -26,7 +26,7 @@ import logging
log = logging.getLogger(__name__)
class NIO_Null(NIO):
class NIONull(NIO):
"""
Dynamips NULL NIO.
@@ -40,8 +40,8 @@ class NIO_Null(NIO):
NIO.__init__(self, hypervisor)
# create an unique ID
self._id = NIO_Null._instance_count
NIO_Null._instance_count += 1
self._id = NIONull._instance_count
NIONull._instance_count += 1
self._name = 'nio_null' + str(self._id)
@classmethod
+3 -3
View File
@@ -26,7 +26,7 @@ import logging
log = logging.getLogger(__name__)
class NIO_TAP(NIO):
class NIOTAP(NIO):
"""
Dynamips TAP NIO.
@@ -41,8 +41,8 @@ class NIO_TAP(NIO):
NIO.__init__(self, hypervisor)
# create an unique ID
self._id = NIO_TAP._instance_count
NIO_TAP._instance_count += 1
self._id = NIOTAP._instance_count
NIOTAP._instance_count += 1
self._name = 'nio_tap' + str(self._id)
self._tap_device = tap_device
+3 -3
View File
@@ -26,7 +26,7 @@ import logging
log = logging.getLogger(__name__)
class NIO_UDP(NIO):
class NIOUDP(NIO):
"""
Dynamips UDP NIO.
@@ -43,8 +43,8 @@ class NIO_UDP(NIO):
NIO.__init__(self, hypervisor)
# create an unique ID
self._id = NIO_UDP._instance_count
NIO_UDP._instance_count += 1
self._id = NIOUDP._instance_count
NIOUDP._instance_count += 1
self._name = 'nio_udp' + str(self._id)
self._lport = lport
self._rhost = rhost
@@ -26,7 +26,7 @@ import logging
log = logging.getLogger(__name__)
class NIO_UDP_auto(NIO):
class NIOUDPAuto(NIO):
"""
Dynamips auto UDP NIO.
@@ -43,8 +43,8 @@ class NIO_UDP_auto(NIO):
NIO.__init__(self, hypervisor)
# create an unique ID
self._id = NIO_UDP_auto._instance_count
NIO_UDP_auto._instance_count += 1
self._id = NIOUDPAuto._instance_count
NIOUDPAuto._instance_count += 1
self._name = 'nio_udp_auto' + str(self._id)
self._laddr = laddr
+3 -3
View File
@@ -26,7 +26,7 @@ import logging
log = logging.getLogger(__name__)
class NIO_UNIX(NIO):
class NIOUNIX(NIO):
"""
Dynamips UNIX NIO.
@@ -42,8 +42,8 @@ class NIO_UNIX(NIO):
NIO.__init__(self, hypervisor)
# create an unique ID
self._id = NIO_UNIX._instance_count
NIO_UNIX._instance_count += 1
self._id = NIOUNIX._instance_count
NIOUNIX._instance_count += 1
self._name = 'nio_unix' + str(self._id)
self._local_file = local_file
self._remote_file = remote_file
+3 -3
View File
@@ -25,7 +25,7 @@ import logging
log = logging.getLogger(__name__)
class NIO_VDE(NIO):
class NIOVDE(NIO):
"""
Dynamips VDE NIO.
@@ -41,8 +41,8 @@ class NIO_VDE(NIO):
NIO.__init__(self, hypervisor)
# create an unique ID
self._id = NIO_VDE._instance_count
NIO_VDE._instance_count += 1
self._id = NIOVDE._instance_count
NIOVDE._instance_count += 1
self._name = 'nio_vde' + str(self._id)
self._control_file = control_file
self._local_file = local_file
+3 -2
View File
@@ -37,13 +37,14 @@ class C1700(Router):
:param vm_id: Router instance identifier
:param project: Project instance
:param manager: Parent VM Manager
:param dynamips_id: ID to use with Dynamips
:param chassis: chassis for this router:
1720, 1721, 1750, 1751 or 1760 (default = 1720).
1710 is not supported.
"""
def __init__(self, name, vm_id, project, manager, chassis="1720"):
Router.__init__(self, name, vm_id, project, manager, platform="c1700")
def __init__(self, name, vm_id, project, manager, dynamips_id, chassis="1720"):
Router.__init__(self, name, vm_id, project, manager, dynamips_id, platform="c1700")
# Set default values for this platform
self._ram = 128
+3 -2
View File
@@ -39,6 +39,7 @@ class C2600(Router):
:param vm_id: Router instance identifier
:param project: Project instance
:param manager: Parent VM Manager
:param dynamips_id: ID to use with Dynamips
:param chassis: chassis for this router:
2610, 2611, 2620, 2621, 2610XM, 2611XM
2620XM, 2621XM, 2650XM or 2651XM (default = 2610).
@@ -57,8 +58,8 @@ class C2600(Router):
"2650XM": C2600_MB_1FE,
"2651XM": C2600_MB_2FE}
def __init__(self, name, vm_id, project, manager, chassis="2610"):
Router.__init__(self, name, vm_id, project, manager, platform="c2600")
def __init__(self, name, vm_id, project, manager, dynamips_id, chassis="2610"):
Router.__init__(self, name, vm_id, project, manager, dynamips_id, platform="c2600")
# Set default values for this platform
self._ram = 128
+3 -2
View File
@@ -36,10 +36,11 @@ class C2691(Router):
:param vm_id: Router instance identifier
:param project: Project instance
:param manager: Parent VM Manager
:param dynamips_id: ID to use with Dynamips
"""
def __init__(self, name, vm_id, project, manager):
Router.__init__(self, name, vm_id, project, manager, platform="c2691")
def __init__(self, name, vm_id, project, manager, dynamips_id):
Router.__init__(self, name, vm_id, project, manager, dynamips_id, platform="c2691")
# Set default values for this platform
self._ram = 192
+3 -2
View File
@@ -36,12 +36,13 @@ class C3600(Router):
:param vm_id: Router instance identifier
:param project: Project instance
:param manager: Parent VM Manager
:param dynamips_id: ID to use with Dynamips
:param chassis: chassis for this router:
3620, 3640 or 3660 (default = 3640).
"""
def __init__(self, name, vm_id, project, manager, chassis="3640"):
Router.__init__(self, name, vm_id, project, manager, platform="c3600")
def __init__(self, name, vm_id, project, manager, dynamips_id, chassis="3640"):
Router.__init__(self, name, vm_id, project, manager, dynamips_id, platform="c3600")
# Set default values for this platform
self._ram = 192
+3 -2
View File
@@ -36,10 +36,11 @@ class C3725(Router):
:param vm_id: Router instance identifier
:param project: Project instance
:param manager: Parent VM Manager
:param dynamips_id: ID to use with Dynamips
"""
def __init__(self, name, vm_id, project, manager):
Router.__init__(self, name, vm_id, project, manager, platform="c3725")
def __init__(self, name, vm_id, project, manager, dynamips_id):
Router.__init__(self, name, vm_id, project, manager, dynamips_id, platform="c3725")
# Set default values for this platform
self._ram = 128
+3 -2
View File
@@ -36,10 +36,11 @@ class C3745(Router):
:param vm_id: Router instance identifier
:param project: Project instance
:param manager: Parent VM Manager
:param dynamips_id: ID to use with Dynamips
"""
def __init__(self, name, vm_id, project, manager):
Router.__init__(self, name, vm_id, project, manager, platform="c3745")
def __init__(self, name, vm_id, project, manager, dynamips_id):
Router.__init__(self, name, vm_id, project, manager, dynamips_id, platform="c3745")
# Set default values for this platform
self._ram = 256
+3 -2
View File
@@ -39,11 +39,12 @@ class C7200(Router):
:param vm_id: Router instance identifier
:param project: Project instance
:param manager: Parent VM Manager
:param dynamips_id: ID to use with Dynamips
:param npe: Default NPE
"""
def __init__(self, name, vm_id, project, manager, npe="npe-400"):
Router.__init__(self, name, vm_id, project, manager, platform="c7200")
def __init__(self, name, vm_id, project, manager, dynamips_id, npe="npe-400"):
Router.__init__(self, name, vm_id, project, manager, dynamips_id, platform="c7200")
# Set default values for this platform
self._ram = 512
+36 -5
View File
@@ -42,20 +42,22 @@ class Router(BaseVM):
:param vm_id: Router instance identifier
:param project: Project instance
:param manager: Parent VM Manager
:param dynamips_id: ID to use with Dynamips
:param platform: Platform of this router
"""
_instances = []
_dynamips_ids = {}
_status = {0: "inactive",
1: "shutting down",
2: "running",
3: "suspended"}
def __init__(self, name, vm_id, project, manager, platform="c7200", ghost_flag=False):
def __init__(self, name, vm_id, project, manager, dynamips_id=None, platform="c7200", ghost_flag=False):
super().__init__(name, vm_id, project, manager)
self._hypervisor = None
self._dynamips_id = dynamips_id
self._closed = False
self._name = name
self._platform = platform
@@ -81,12 +83,26 @@ class Router(BaseVM):
self._confreg = "0x2102"
self._console = None
self._aux = None
self._mac_addr = None
self._mac_addr = ""
self._system_id = "FTX0945W0MY" # processor board ID in IOS
self._slots = []
self._ghost_flag = ghost_flag
if not ghost_flag:
self._dynamips_ids.setdefault(project.id, list())
if not dynamips_id:
# find a Dynamips ID if none is provided (0 < id <= 4096)
self._dynamips_id = 0
for identifier in range(1, 4097):
if identifier not in self._dynamips_ids[project.id]:
self._dynamips_id = identifier
break
if self._dynamips_id == 0:
raise DynamipsError("Maximum number of Dynamips instances reached")
else:
if dynamips_id in self._dynamips_ids[project.id]:
raise DynamipsError("Dynamips identifier {} is already used by another router".format(dynamips_id))
self._dynamips_ids[project.id].append(self._dynamips_id)
if self._console is not None:
self._console = self._manager.port_manager.reserve_console_port(self._console)
@@ -97,12 +113,17 @@ class Router(BaseVM):
self._aux = self._manager.port_manager.reserve_console_port(self._aux)
else:
self._aux = self._manager.port_manager.get_free_console_port()
else:
log.info("creating a new ghost IOS file")
self._dynamips_id = 0
self._name = "Ghost"
def __json__(self):
router_info = {"name": self.name,
"vm_id": self.id,
"project_id": self.project.id,
"dynamips_id": self._dynamips_id,
"platform": self._platform,
"image": self._image,
"startup_config": self._startup_config,
@@ -138,14 +159,21 @@ class Router(BaseVM):
return router_info
@classmethod
def reset(cls):
"""
Resets the instance count and the allocated instances list.
"""
cls._dynamips_ids.clear()
@asyncio.coroutine
def create(self):
self._hypervisor = yield from self.manager.start_new_hypervisor()
print("{} {} {}".format(self._name, self._id, self._platform))
yield from self._hypervisor.send('vm create "{name}" {id} {platform}'.format(name=self._name,
id=1, #FIXME: instance ID!
id=self._dynamips_id,
platform=self._platform))
if not self._ghost_flag:
@@ -270,6 +298,9 @@ class Router(BaseVM):
self._manager.port_manager.release_console_port(self._aux)
self._aux = None
if self._dynamips_id in self._dynamips_ids[self._project.id]:
self._dynamips_ids[self._project.id].remove(self._dynamips_id)
self._closed = True
@asyncio.coroutine