Chassis and private-config support

pull/11/head
grossmj 10 years ago
parent 0e1d8e5071
commit 99cc7345b8

@ -20,6 +20,7 @@ Dynamips server module.
""" """
import os import os
import base64
import tempfile import tempfile
from gns3server.modules import IModule from gns3server.modules import IModule
import gns3server.jsonrpc as jsonrpc import gns3server.jsonrpc as jsonrpc
@ -362,6 +363,35 @@ class Dynamips(IModule):
router.ghost_status = 2 router.ghost_status = 2
router.ghost_file = ghost_instance router.ghost_file = ghost_instance
def save_base64config(self, config_base64, router, config_filename):
"""
Saves a base64 encoded config (decoded) to a file.
:param config_base64: base64 encoded config
:param router: router instance
:param config_filename: file name to save the config
:returns: relative path to the config file
"""
config = base64.decodestring(config_base64.encode("utf-8")).decode("utf-8")
config = "!\n" + config.replace("\r", "")
config = config.replace('%h', router.name)
config_dir = os.path.join(router.hypervisor.working_dir, "configs")
if not os.path.exists(config_dir):
try:
os.makedirs(config_dir)
except EnvironmentError as e:
raise DynamipsError("Could not create configs directory: {}".format(e))
config_path = os.path.join(config_dir, config_filename)
try:
with open(config_path, "w") as f:
log.info("saving startup-config to {}".format(config_path))
f.write(config)
except EnvironmentError as e:
raise DynamipsError("Could not save the configuration {}: {}".format(config_path, e))
return "configs" + os.sep + os.path.basename(config_path)
@IModule.route("dynamips.nio.get_interfaces") @IModule.route("dynamips.nio.get_interfaces")
def nio_get_interfaces(self, request): def nio_get_interfaces(self, request):
""" """

@ -101,6 +101,7 @@ class VM(object):
- console (console port number) - console (console port number)
- aux (auxiliary console port number) - aux (auxiliary console port number)
- mac_addr (MAC address) - mac_addr (MAC address)
- chassis (router chassis model)
Response parameters: Response parameters:
- id (vm identifier) - id (vm identifier)
@ -123,6 +124,9 @@ class VM(object):
image = request["image"] image = request["image"]
ram = request["ram"] ram = request["ram"]
hypervisor = None hypervisor = None
chassis = None
if "chassis" in request:
chassis = request["chassis"]
try: try:
@ -131,7 +135,10 @@ class VM(object):
hypervisor = self._hypervisor_manager.allocate_hypervisor_for_router(image, ram) hypervisor = self._hypervisor_manager.allocate_hypervisor_for_router(image, ram)
router = PLATFORMS[platform](hypervisor, name) if chassis:
router = PLATFORMS[platform](hypervisor, name, chassis=chassis)
else:
router = PLATFORMS[platform](hypervisor, name)
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
@ -341,6 +348,7 @@ class VM(object):
Optional request parameters: Optional request parameters:
- any setting to update - any setting to update
- startup_config_base64 (startup-config base64 encoded) - startup_config_base64 (startup-config base64 encoded)
- private_config_base64 (private-config base64 encoded)
Response parameters: Response parameters:
- same as original request - same as original request
@ -360,25 +368,18 @@ class VM(object):
try: try:
# a new startup-config has been pushed # a new startup-config has been pushed
if "startup_config_base64" in request: if "startup_config_base64" in request:
config = base64.decodestring(request["startup_config_base64"].encode("utf-8")).decode("utf-8") config_filename = "{}.cfg".format(router.name)
config = "!\n" + config.replace("\r", "") request["startup_config"] = self.save_base64config(request["startup_config_base64"], router, config_filename)
config = config.replace('%h', router.name)
config_dir = os.path.join(router.hypervisor.working_dir, "configs")
if not os.path.exists(config_dir):
try:
os.makedirs(config_dir)
except EnvironmentError as e:
raise DynamipsError("Could not create configs directory: {}".format(e))
config_path = os.path.join(config_dir, "{}.cfg".format(router.name))
try:
with open(config_path, "w") as f:
log.info("saving startup-config to {}".format(config_path))
f.write(config)
except EnvironmentError as e:
raise DynamipsError("Could not save the configuration {}: {}".format(config_path, e))
request["startup_config"] = "configs" + os.sep + os.path.basename(config_path)
if "startup_config" in request: if "startup_config" in request:
router.set_config(request["startup_config"]) router.set_config(request["startup_config"])
# a new private-config has been pushed
if "private_config_base64" in request:
config_filename = "{}-private.cfg".format(router.name)
request["private_config"] = self.save_base64config(request["private_config_base64"], router, config_filename)
if "private_config" in request:
router.set_config(router.startup_config, request["private_config"])
except DynamipsError as e: except DynamipsError as e:
self.send_custom_error(str(e)) self.send_custom_error(str(e))
return return
@ -455,9 +456,9 @@ class VM(object):
router_id = request["id"] router_id = request["id"]
router = self._routers[router_id] router = self._routers[router_id]
try: try:
if router.startup_config: if router.startup_config or router.private_config:
#TODO: handle private-config
startup_config_base64, _ = router.extract_config() startup_config_base64, private_config_base64 = router.extract_config()
if startup_config_base64: if startup_config_base64:
try: try:
config = base64.decodestring(startup_config_base64.encode("utf-8")).decode("utf-8") config = base64.decodestring(startup_config_base64.encode("utf-8")).decode("utf-8")
@ -467,7 +468,19 @@ class VM(object):
log.info("saving startup-config to {}".format(router.startup_config)) log.info("saving startup-config to {}".format(router.startup_config))
f.write(config) f.write(config)
except EnvironmentError as e: except EnvironmentError as e:
raise DynamipsError("Could not save the configuration {}: {}".format(config_path, e)) raise DynamipsError("Could not save the startup configuration {}: {}".format(config_path, e))
if private_config_base64:
try:
config = base64.decodestring(private_config_base64.encode("utf-8")).decode("utf-8")
config = "!\n" + config.replace("\r", "")
config_path = os.path.join(router.hypervisor.working_dir, router.private_config)
with open(config_path, "w") as f:
log.info("saving private-config to {}".format(router.private_config))
f.write(config)
except EnvironmentError as e:
raise DynamipsError("Could not save the private configuration {}: {}".format(config_path, e))
except DynamipsError as e: except DynamipsError as e:
log.warn("could not save config to {}: {}".format(router.startup_config, e)) log.warn("could not save config to {}: {}".format(router.startup_config, e))

@ -86,7 +86,9 @@ class C7200(Router):
"disk1": self._disk1, "disk1": self._disk1,
"npe": self._npe, "npe": self._npe,
"midplane": self._midplane, "midplane": self._midplane,
"clock_divisor": self._clock_divisor} "clock_divisor": self._clock_divisor,
"sensors": self._sensors,
"power_supplies": self._power_supplies}
# update the router defaults with the platform specific defaults # update the router defaults with the platform specific defaults
router_defaults.update(platform_defaults) router_defaults.update(platform_defaults)
@ -230,3 +232,17 @@ class C7200(Router):
power_supply_id += 1 power_supply_id += 1
self._power_supplies = power_supplies self._power_supplies = power_supplies
def start(self):
"""
Starts this router.
At least the IOS image must be set before starting it.
"""
# trick: we must send sensors and power supplies info after starting the router
# otherwise they are not taken into account (Dynamips bug?)
Router.start(self)
if self._sensors != [22, 22, 22, 22]:
self.sensors = self._sensors
if self._power_supplies != [1, 1]:
self.power_supplies = self._power_supplies

@ -452,11 +452,15 @@ class Router(object):
id=self._id, id=self._id,
startup='"' + startup_config + '"')) startup='"' + startup_config + '"'))
self._startup_config = startup_config
if private_config: if private_config:
log.info("router {name} [id={id}]: has a private-config set: {private}".format(name=self._name, log.info("router {name} [id={id}]: has a private-config set: {private}".format(name=self._name,
id=self._id, id=self._id,
private='"' + private_config + '"')) private='"' + private_config + '"'))
self._private_config = private_config
def extract_config(self): def extract_config(self):
""" """
Gets the contents of the config files Gets the contents of the config files
@ -1180,9 +1184,9 @@ class Router(object):
# Generate an OIR event if the router is running and # Generate an OIR event if the router is running and
# only for c7200, c3600 and c3745 (NM-4T only) # only for c7200, c3600 and c3745 (NM-4T only)
if self.is_running() and self._platform == 'c7200' \ if self.is_running() and (self._platform == 'c7200' \
or (self._platform == 'c3600' and self.chassis == '3660') \ or (self._platform == 'c3600' and self.chassis == '3660') \
or (self._platform == 'c3745' and adapter == 'NM-4T'): or (self._platform == 'c3745' and adapter == 'NM-4T')):
self._hypervisor.send("vm slot_oir_start {name} {slot_id} 0".format(name=self._name, self._hypervisor.send("vm slot_oir_start {name} {slot_id} 0".format(name=self._name,
slot_id=slot_id)) slot_id=slot_id))
@ -1212,9 +1216,9 @@ class Router(object):
# Generate an OIR event if the router is running and # Generate an OIR event if the router is running and
# only for c7200, c3600 and c3745 (NM-4T only) # only for c7200, c3600 and c3745 (NM-4T only)
if self.is_running() and self._platform == 'c7200' \ if self.is_running() and (self._platform == 'c7200' \
or (self._platform == 'c3600' and self.chassis == '3660') \ or (self._platform == 'c3600' and self.chassis == '3660') \
or (self._platform == 'c3745' and adapter == 'NM-4T'): or (self._platform == 'c3745' and adapter == 'NM-4T')):
self._hypervisor.send("vm slot_oir_stop {name} {slot_id} 0".format(name=self._name, self._hypervisor.send("vm slot_oir_stop {name} {slot_id} 0".format(name=self._name,
slot_id=slot_id)) slot_id=slot_id))

Loading…
Cancel
Save